имам някои конфигурационни файлове (всъщност изнасяме от докладите на защитната стена), които използват този вид структура:
policies {
apply-groups default-log;
from-zone Trust to-zone DMZ {
policy policy-66 {
match {
source-address g_DMZ_SRV_;
destination-address g_DMZ_SRV;
application any;
}
then {
permit;
}
}
policy policy-9 {
match {
source-address g_h_OpenMail-Server;
destination-address g_in_DMZ_Exchange;
application t_1023;
}
then {
permit;
}
}
}
from-zone DMZ to-zone Blabla {
policy policy-68 {
match {
source-address g_DMZ_SRV_2_;
destination-address g_DMZ_SRV_3;
application T_22-ssh;
}
then {
permit;
}
}
policy policy-95 {
match {
source-address g_h_OpenMail-Server-2;
source-address 1.2.0.3;
destination-address g_in_DMZ_Exchange-1;
destination-address 10.25.32.64;
application t_1024;
}
then {
permit;
}
}
}
}
и бих искал да го разбера в Perl, за да изградя хеш например (или просто да поставя условия за третиране на данните), които бих могъл да използвам след това, например нещо като:
Trust-to-DMZ
policy-66
source => g_DMZ_SRV
destination => blabla
policy-44
source => source1
source2
source3
destination => dest1
ports => port1
DMZ-to-Trust
policy-XX
исках да знам:
ако знаеше, че някои модули помагат в такава задача (предполагам, че бих могъл да използвам Текст :: Балансиран, намерих някои примери в няколко други публикации)
дали има някои методи / най-добри практики, за да се избегне мръсната работа?
Предполагам, че бих могъл да "преброя" броя на скобите и да направя примки в контурите .. но би било мръсно.
не съществува ли по-лесно решение или модул да прави това автоматично? (като модули съществуват например за XML файлове, XML :: Simple поставяне на съдържанието на XML в хеш, Бих очаквал нещо подобно за такива неща ?)
в противен случай ще започна да кодирам нещо мръсно и да публикувам напредъка си тук
Благодаря!
редактиране на 8 юни, така че да знаете, че работи с мръсен мръсенмръсен код като този (аз не съм разработчик, извинявам се), което не е точно това, което искам, тъй като не е приспособимо .. предупреден си! :) така че не гледайте, ако не искате кръв в очите ви
use warnings;
use lib "/opt/csm/64-bit/cpan/5.16.3-2013.03/lib";
use Data::Dumper;
my ( $policies_flag, $fromzone_flag, $policy_flag, $match_flag, $zone_flag ) = ( 0,0,0,0,0 );
my ( $details_flag, $clos_flag, $then_flag, $permit_flag, $clos2_flag, $final_flag ) = ( 0,0,0,0,0,0 );
my $fromzone;
my $tozone;
my %pols;
my $clos_counter;
die "Usage: $0 <path_to_file>" if $ARGV[0] eq "";
open D, "<", $ARGV[0] or die "cannot open $ARGV[0] for readn";
@data = <D>;
close D;
OUTER: foreach my $str (@data) {
next if $str =~ /^$/;
next if $str =~ /apply-groups/;
chomp $str;
if ( $str =~ /s*policiess+{/ ) {
$policies_flag = 1;
next OUTER;
}
# policies
if ($policies_flag == 1) {
if ($str =~ /from-zonesS+sto-zonesS+s{$/) {
next if $str =~ /(<|>)/;
( $fromzone, $tozone ) = ( split(/s+/,$str) )[2,4];
$fromzone_flag = 1;
next OUTER;
}
# from-zone
if ($fromzone_flag == 1) {
if ($str =~ /policys+S+s+{/) {
$policy_flag = 1;
$clos_counter=0;
( $policy_name ) = ( split(/s+/, $str) )[2];
$pols{$policy_name}{from_zone} = "$fromzone";
$pols{$policy_name}{to_zone} = "$tozone";
next OUTER;
}
# pol
if ($policy_flag == 1) {
if ($str =~ /matchs+{/) {
$match_flag = 1;
next OUTER;
}
}
# match
if ($match_flag == 1) {
if ($str =~ /S+s+S+;$/) {
$details_flag = 1;
if ($str =~ /source-address/) {
( $sources ) = ( split(/s+/, $str) )[2];
$sources =~ s/;//;
push( @{$pols{$policy_name}{sources}}, "$sources");
} elsif ($str =~ /destination-address/) {
( $dests ) = ( split(/s+/, $str) )[2];
$dests =~ s/;//;
push( @{$pols{$policy_name}{destinations}}, "$dests");
} elsif ($str =~ /application/) {
( $ports ) = ( split(/s+/, $str) )[2];
$ports =~ s/;//;
push( @{$pols{$policy_name}{ports}}, "$ports");
}
next OUTER;
}
}
# rest
if ($details_flag == 1) {
if ($str =~ /s*}s*$/) {
if ($clos_counter == 0) {
$clos_flag = 1;
$clos_counter++;
next OUTER;
}
}
}
# then
if ($clos_flag == 1) {
if ($str =~ /s*thens+{$/) {
$then_flag = 1;
next OUTER;
}
}
# permit
if ($then_flag == 1) {
if ($str =~ /s*permit;$/) {
$permit_flag = 1;
$pols{$policy_name}{action} = ( split(/s+/,$str) )[1];
next OUTER;
}
}
# clos2
if ($permit_flag == 1) {
if ($str =~ /s*}s*$/) {
if ($clos_counter == 1) {
$clos2_flag = 1;
$clos_counter++;
next OUTER;
}
}
}
# final close
if ($clos2_flag == 1) {
if ($str =~ /s*}s*$/) {
if ($clos_counter == 2) {
$final_flag = 1;
$clos_counter++;
next OUTER;
}
}
}
# ultimate zone
if ($final_flag == 1) {
if ($str =~ /s*}s*$/) {
if ($clos_counter == 3) {
$zone_flag = 1;
$clos_counter++;
next OUTER;
}
}
}
# ulti pols
if ($zone_flag == 1) {
if ($str =~ /s*}s*$/) {
if ($clos_counter == 4) {
$clos_counter++;
last OUTER;
}
}
}
}
}
}
print Dumper(%pols);
което дава:
$VAR1 = {
"policy-68" => {
"ports" => [
"T_22-ssh"
],
"sources" => [
"g_DMZ_SRV_2_"
],
"to_zone" => "Blabla",
"from_zone" => "DMZ",
"action" => "permit;",
"destinations" => [
"g_DMZ_SRV_3"
]
},
"policy-9" => {
"ports" => [
"t_1023"
],
"sources" => [
"g_h_OpenMail-Server"
],
"to_zone" => "DMZ",
"from_zone" => "Trust",
"action" => "permit;",
"destinations" => [
"g_in_DMZ_Exchange"
]
},
"policy-66" => {
"ports" => [
"any"
],
"sources" => [
"g_DMZ_SRV_"
],
"to_zone" => "DMZ",
"from_zone" => "Trust",
"action" => "permit;",
"destinations" => [
"g_DMZ_SRV"
]
},
"policy-95" => {
"ports" => [
"t_1024"
],
"sources" => [
"g_h_OpenMail-Server-2",
"1.2.0.3"
],
"to_zone" => "Blabla",
"from_zone" => "DMZ",
"action" => "permit;",
"destinations" => [
"g_in_DMZ_Exchange-1",
"10.25.32.64"
]
}
};
Отговори:
1 за отговор № 1По мое вероятно не напълно обективно мнение, Марпа :: R2 е добър начин за решаване на проблема ви.
1 за отговор № 2
Рон Савидж от общността на Марпа излезе със следното:
моят ($ parser) = текст :: балансиран ::Marpa -> нов ( open => ["{"], close => ["}", ); my ($ text) = read_text ("policies.txt"); my ($ result) = $ parser -> разбор (текст => $ текст); print "Разбор на резултата: $ result (0 е успех) n"; #print join ("n", @ {$ parser -> дърво -> tree2string}), "n"; ми ($ тире); за моя $ node ($ parser -> tree -> траверс ($ parser -> дърво -> POST_ORDER)) { $ indent = "" x $ node -> дълбочина; $ text = $ {$ node -> meta} {текст} = ~ s / n | [{}] // gr; say $ indent, $ text if ($ text); }
Output:
Parse result: 0 (0 is success)
policies
apply-groups default-log; from-zone Trust to-zone DMZ
policy policy-66
match
source-address g_DMZ_SRV_; destination-address g_DMZ_SRV; application any;
then
permit;
policy policy-9
match
source-address g_h_OpenMail-Server; destination-address g_in_DMZ_Exchange; application t_1023;
then
permit;
from-zone DMZ to-zone Blabla
policy policy-68
match
source-address g_DMZ_SRV_2_; destination-address g_DMZ_SRV_3; application T_22-ssh;
then
permit;
policy policy-95
match
source-address g_h_OpenMail-Server-2; source-address 1.2.0.3; destination-address g_in_DMZ_Exchange-1; destination-address 10.25.32.64; application t_1024;
then
permit;
Това същност съдържа горния код и изход. Форматът на Stackoverflow настоява да се вмъкне всичко само, независимо дали го разбира или не - на същността може да се разчита да съдържа копие преди повреда.