Skip to content

Commit 5ac4f80

Browse files
committed
migrated firewall resource to new interface
1 parent fef1711 commit 5ac4f80

File tree

4 files changed

+226
-219
lines changed

4 files changed

+226
-219
lines changed

lib/Rex/Resource/firewall.pm

Lines changed: 49 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -75,76 +75,56 @@ my $__provider = { default => "Rex::Resource::firewall::Provider::iptables", };
7575
7676
=cut
7777

78-
resource "firewall", { export => 1 }, sub {
79-
my $rule_name = resource_name;
80-
81-
my $rule_config = {
82-
action => param_lookup("action"),
83-
ensure => param_lookup( "ensure", "present" ),
84-
proto => param_lookup( "proto", undef ),
85-
source => param_lookup( "source", undef ),
86-
destination => param_lookup( "destination", undef ),
87-
port => param_lookup( "port", undef ),
88-
app => param_lookup( "app", undef ),
89-
sport => param_lookup( "sport", undef ),
90-
sapp => param_lookup( "sapp", undef ),
91-
dport => param_lookup( "dport", undef ),
92-
dapp => param_lookup( "dapp", undef ),
93-
tcp_flags => param_lookup( "tcp_falgs", undef ),
94-
chain => param_lookup( "chain", "input" ),
95-
table => param_lookup( "table", "filter" ),
96-
iniface => param_lookup( "iniface", undef ),
97-
outiface => param_lookup( "outiface", undef ),
98-
reject_with => param_lookup( "reject_with", undef ),
99-
logging => param_lookup( "logging", undef ), # overall logging
100-
log => param_lookup( "log", undef ), # logging for rule
101-
log_level => param_lookup( "log_level", undef ), # logging for rule
102-
log_prefix => param_lookup( "log_prefix", undef ),
103-
state => param_lookup( "state", undef ),
104-
ip_version => param_lookup( "ip_version", -4 ),
105-
};
106-
107-
my $provider =
108-
param_lookup( "provider", case ( lc(operating_system), $__provider ) );
109-
110-
if ( $provider !~ m/::/ ) {
111-
$provider = "Rex::Resource::firewall::Provider::$provider";
112-
}
113-
78+
resource "firewall", {
79+
export => 1,
80+
params_list => [
81+
name => {
82+
isa => 'Str',
83+
default => sub { shift }
84+
},
85+
ensure => {
86+
isa => 'Str',
87+
default => sub { "present" }
88+
},
89+
action => { isa => 'Str | Undef', default => undef },
90+
proto => { isa => 'Str | Undef', default => "tcp" },
91+
source => { isa => 'Str | Undef', default => undef },
92+
destination => { isa => 'Str | Undef', default => undef },
93+
port => { isa => 'Int | Undef', default => undef },
94+
source => { isa => 'Str | Undef', default => undef },
95+
app => { isa => 'Str | Undef', default => undef },
96+
sport => { isa => 'Int | Undef', default => undef },
97+
dport => {
98+
isa => 'Int | Undef',
99+
default => sub { my ( $name, %p ) = @_; return $p{port}; },
100+
},
101+
dapp => { isa => 'Str | Undef', default => undef },
102+
tcp_flags => { isa => 'ArrayRef | Undef', default => undef },
103+
chain => { isa => 'Str | Undef', default => "INPUT" },
104+
table => { isa => 'Str | Undef', default => undef },
105+
iniface => { isa => 'Str | Undef', default => undef },
106+
outiface => { isa => 'Str | Undef', default => undef },
107+
reject_with => { isa => 'Str | Undef', default => undef },
108+
logging => { isa => 'Str | Undef', default => undef },
109+
log => { isa => 'Str | Undef', default => undef },
110+
log_level => { isa => 'Str | Undef', default => undef },
111+
log_prefix => { isa => 'Str | Undef', default => undef },
112+
state => { isa => 'Str | Undef', default => undef },
113+
ip_version => { isa => 'Str | Undef', default => "-4" },
114+
],
115+
},
116+
sub {
117+
my ( $name, %args ) = @_;
118+
119+
my $provider = resolve_resource_provider( $args{provider}
120+
|| case ( lc(operating_system), $__provider ) );
121+
122+
# TODO define provider type automatically.
114123
$provider->require;
115-
my $provider_o = $provider->new();
116-
117-
my $changed = 0;
118-
if ( my $logging = $rule_config->{logging} ) {
119-
if ( $provider_o->logging($logging) ) {
120-
emit changed, "Firewall logging updated.";
121-
}
122-
}
123-
elsif ( $rule_config->{ensure} eq "present" ) {
124-
if ( $provider_o->present($rule_config) ) {
125-
emit created, "Firewall rule created.";
126-
}
127-
}
128-
elsif ( $rule_config->{ensure} eq "absent" ) {
129-
if ( $provider_o->absent($rule_config) ) {
130-
emit removed, "Firewall rule removed.";
131-
}
132-
}
133-
elsif ( $rule_config->{ensure} eq "disabled" ) {
134-
if ( $provider_o->disable($rule_config) ) {
135-
emit changed, "Firewall disabled.";
136-
}
137-
}
138-
elsif ( $rule_config->{ensure} eq "enabled" ) {
139-
if ( $provider_o->enable($rule_config) ) {
140-
emit changed, "Firewall enabled.";
141-
}
142-
}
143-
else {
144-
die "Error: $rule_config->{ensure} not a valid option for 'ensure'.";
145-
}
146-
147-
};
124+
my $provider_o =
125+
$provider->new( type => "firewall", name => $name, config => \%args );
126+
$provider_o->process;
127+
};
148128

149129
=back
150130

lib/Rex/Resource/firewall/Provider/base.pm

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,8 @@ use warnings;
1313

1414
use Data::Dumper;
1515

16-
sub new {
17-
my $that = shift;
18-
my $proto = ref($that) || $that;
19-
my $self = {@_};
16+
use Moose;
2017

21-
bless( $self, $proto );
22-
23-
return $self;
24-
}
25-
26-
sub present {
27-
my ( $self, $rule_config ) = @_;
28-
die "Must be implemented by provider.";
29-
}
30-
31-
sub absent {
32-
my ( $self, $rule_config ) = @_;
33-
die "Must be implemented by provider.";
34-
}
35-
36-
sub enable {
37-
my ( $self, $rule_config ) = @_;
38-
Rex::Logger::debug("enable: Not implemented by provider.");
39-
}
40-
41-
sub disable {
42-
my ( $self, $rule_config ) = @_;
43-
Rex::Logger::debug("disable: Not implemented by provider.");
44-
}
45-
46-
sub logging {
47-
my ( $self, $rule_config ) = @_;
48-
Rex::Logger::debug("logging: Not implemented by provider.");
49-
}
18+
extends qw(Rex::Resource::Provider);
5019

5120
1;

lib/Rex/Resource/firewall/Provider/iptables.pm

Lines changed: 76 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -11,96 +11,97 @@ use warnings;
1111

1212
# VERSION
1313

14+
use Moose;
15+
16+
extends qw(Rex::Resource::firewall::Provider::base);
17+
with qw(Rex::Resource::Role::Ensureable);
18+
1419
use Rex::Commands::Iptables;
1520
use Rex::Helper::Run;
21+
use Rex::Resource::Common;
22+
1623
use Data::Dumper;
17-
use base qw(Rex::Resource::firewall::Provider::base);
1824

19-
sub new {
20-
my $that = shift;
21-
my $proto = ref($that) || $that;
22-
my $self = $proto->SUPER::new(@_);
25+
sub test {
26+
my ($self) = @_;
27+
28+
my $rule_config = $self->config;
29+
my @iptables_rule = $self->_build_iptables_array("A");
2330

24-
bless( $self, $proto );
31+
my $exists =
32+
Rex::Commands::Iptables::_rule_exists( $rule_config->{ip_version},
33+
@iptables_rule );
2534

26-
return $self;
35+
if ( $self->config->{ensure} eq "absent" && $exists ) {
36+
return 0;
37+
}
38+
elsif ( $self->config->{ensure} eq "present" && !$exists ) {
39+
return 0;
40+
}
41+
42+
return 1;
2743
}
2844

2945
sub present {
30-
my ( $self, $rule_config ) = @_;
46+
my ($self) = @_;
3147

32-
my @iptables_rule = ();
48+
my @iptables_rule = $self->_build_iptables_array("A");
49+
my $exit_code = 0;
50+
eval {
51+
iptables( $self->config->{ip_version}, @iptables_rule );
52+
1;
53+
} or do {
54+
$exit_code = 1;
55+
};
56+
57+
return {
58+
value => "",
59+
exit_code => $exit_code,
60+
changed => 1,
61+
status => ( $exit_code == 0 ? state_changed : state_failed ),
62+
};
63+
}
3364

34-
$rule_config->{dport} ||= $rule_config->{port};
35-
$rule_config->{proto} ||= 'tcp';
36-
$rule_config->{chain} ||= 'INPUT';
37-
$rule_config->{ip_version} ||= -4;
65+
sub absent {
66+
my ($self) = @_;
3867

39-
if ( $rule_config->{source}
40-
&& $rule_config->{source} !~ m/\/(\d+)$/
41-
&& $self->_version()->[0] >= 1
42-
&& $self->_version()->[1] >= 4 )
43-
{
44-
$rule_config->{source} .= "/32";
45-
}
68+
my @iptables_rule = $self->_build_iptables_array("D");
69+
my $exit_code = 0;
70+
eval {
71+
iptables( $self->config->{ip_version}, @iptables_rule );
72+
1;
73+
} or do {
74+
$exit_code = 1;
75+
};
76+
77+
return {
78+
value => "",
79+
exit_code => $exit_code,
80+
changed => 1,
81+
status => ( $exit_code == 0 ? state_changed : state_failed ),
82+
};
83+
}
4684

47-
push( @iptables_rule, t => $rule_config->{table} )
48-
if ( defined $rule_config->{table} );
49-
push( @iptables_rule, A => uc( $rule_config->{chain} ) )
50-
if ( defined $rule_config->{chain} );
51-
push( @iptables_rule, p => $rule_config->{proto} )
52-
if ( defined $rule_config->{proto} );
53-
push( @iptables_rule, m => $rule_config->{proto} )
54-
if ( defined $rule_config->{proto} );
55-
push( @iptables_rule, s => $rule_config->{source} )
56-
if ( defined $rule_config->{source} );
57-
push( @iptables_rule, d => $rule_config->{destination} )
58-
if ( defined $rule_config->{destination} );
59-
push( @iptables_rule, sport => $rule_config->{sport} )
60-
if ( defined $rule_config->{sport} );
61-
push( @iptables_rule, dport => $rule_config->{dport} )
62-
if ( defined $rule_config->{dport} );
63-
push( @iptables_rule, "tcp-flags" => $rule_config->{tcp_flags} )
64-
if ( defined $rule_config->{tcp_flags} );
65-
push( @iptables_rule, "i" => $rule_config->{iniface} )
66-
if ( defined $rule_config->{iniface} );
67-
push( @iptables_rule, "o" => $rule_config->{outiface} )
68-
if ( defined $rule_config->{outiface} );
69-
push( @iptables_rule, "reject-with" => $rule_config->{reject_with} )
70-
if ( defined $rule_config->{reject_with} );
71-
push( @iptables_rule, "log-level" => $rule_config->{log_level} )
72-
if ( defined $rule_config->{log_level} );
73-
push( @iptables_rule, "log-prefix" => $rule_config->{log_prefix} )
74-
if ( defined $rule_config->{log_prefix} );
75-
push( @iptables_rule, "state" => $rule_config->{state} )
76-
if ( defined $rule_config->{state} );
77-
push( @iptables_rule, j => uc( $rule_config->{action} ) )
78-
if ( defined $rule_config->{action} );
85+
sub _version {
86+
my ($self) = @_;
87+
if ( exists $self->{__version__} ) { return $self->{__version__} }
7988

80-
if (
81-
!Rex::Commands::Iptables::_rule_exists(
82-
$rule_config->{ip_version},
83-
@iptables_rule
84-
)
85-
)
86-
{
87-
iptables( $rule_config->{ip_version}, @iptables_rule );
88-
return 1;
89-
}
89+
my $version = i_run "iptables --version";
90+
$version =~ s/^.*\sv(\d+\.\d+\.\d+)/$1/;
9091

91-
return 0;
92-
}
92+
$self->{__version__} = [ split( /\./, $version ) ];
9393

94-
sub absent {
95-
my ( $self, $rule_config ) = @_;
94+
Rex::Logger::debug(
95+
"Got iptables version: " . join( ", ", @{ $self->{__version__} } ) );
9696

97-
my @iptables_rule = ();
97+
return $self->{__version__};
98+
}
9899

99-
$rule_config->{dport} ||= $rule_config->{port};
100-
$rule_config->{proto} ||= 'tcp';
101-
$rule_config->{chain} ||= 'INPUT';
100+
sub _build_iptables_array {
101+
my ( $self, $type ) = @_;
102+
my $rule_config = $self->config;
102103

103-
$rule_config->{ip_version} ||= -4;
104+
my @iptables_rule = ();
104105

105106
if ( $rule_config->{source}
106107
&& $rule_config->{source} !~ m/\/(\d+)$/
@@ -112,14 +113,14 @@ sub absent {
112113

113114
push( @iptables_rule, t => $rule_config->{table} )
114115
if ( defined $rule_config->{table} );
115-
push( @iptables_rule, D => uc( $rule_config->{chain} ) )
116+
push( @iptables_rule, $type => uc( $rule_config->{chain} ) )
116117
if ( defined $rule_config->{chain} );
117-
push( @iptables_rule, s => $rule_config->{source} )
118-
if ( defined $rule_config->{source} );
119118
push( @iptables_rule, p => $rule_config->{proto} )
120119
if ( defined $rule_config->{proto} );
121120
push( @iptables_rule, m => $rule_config->{proto} )
122121
if ( defined $rule_config->{proto} );
122+
push( @iptables_rule, s => $rule_config->{source} )
123+
if ( defined $rule_config->{source} );
123124
push( @iptables_rule, d => $rule_config->{destination} )
124125
if ( defined $rule_config->{destination} );
125126
push( @iptables_rule, sport => $rule_config->{sport} )
@@ -143,33 +144,7 @@ sub absent {
143144
push( @iptables_rule, j => uc( $rule_config->{action} ) )
144145
if ( defined $rule_config->{action} );
145146
146-
if (
147-
Rex::Commands::Iptables::_rule_exists(
148-
$rule_config->{ip_version},
149-
@iptables_rule
150-
)
151-
)
152-
{
153-
iptables( $rule_config->{ip_version}, @iptables_rule );
154-
return 1;
155-
}
156-
157-
return 0;
158-
}
159-
160-
sub _version {
161-
my ($self) = @_;
162-
if ( exists $self->{__version__} ) { return $self->{__version__} }
163-
164-
my $version = i_run "iptables --version", fail_ok => 1;
165-
$version =~ s/^.*\sv(\d+\.\d+\.\d+)/$1/;
166-
167-
$self->{__version__} = [ split( /\./, $version ) ];
168-
169-
Rex::Logger::debug(
170-
"Got iptables version: " . join( ", ", @{ $self->{__version__} } ) );
171-
172-
return $self->{__version__};
147+
return @iptables_rule;
173148
}
174149
175150
1;

0 commit comments

Comments
 (0)