Расширение рекурсивной переменной в Perl - PullRequest
0 голосов
/ 14 января 2019

Мне нужно расширить списки доступа ASA для справки после миграции. ASA уже нет, и я хочу расширить ссылки на группы объектов, чтобы проверить, что мы захватили все ожидаемые права доступа. У меня есть рабочая идея для линии ACL с 4 объектными группами. Моя проблема в том, что списки ACL могут иметь 0-4 ссылки на группу объектов, и мне нужен цикл для прохождения и обработки каждой возможной комбинации. Я могу написать цикл для каждой возможной комбинации, но я знаю, что должен быть более элегантный способ.

У меня уже есть код для расширения и сохранения групп объектов по отдельности, но их замена в строке - это сложная задача.

Спасибо за ваше время и внимание.

@line = ('access-list','vlan_in','extended','permit','object-group','ob1','object-group','ob2','object-group','ob3','object-group','ob4');
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','object-group','ob2','object-group','ob3','eq','53');
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','host','30.0.0.30','object-group','ob2','eq','23');
# @line = ('access-list','vlan_in','extended','permit','tcp','host','40.0.0.10','object-group','ob1','eq 80');

$OG{'ob1'} = ['tcp','udp'];
$OG{'ob2'} = ['10.0.0.10', '10.0.0.20'];
$OG{'ob3'} = ['20.0.0.15', '20.0.0.25'];
$OG{'ob4'} = ['eq 22', 'eq 443'];

foreach $ins4 (@{$OG{ob4}}) {
  foreach $ins1 (@{$OG{ob1}}) {
    foreach $ins2 (@{$OG{ob2}}) {
      foreach $ins3(@{$OG{ob3}}) {
        $buffer = "";
        foreach $element (@line) {
          if($element =~ /object-group/) { next; }
          $buffer = $buffer . ' ' . $element;
        }
        $buffer =~ s/ob1/$ins1/;
        $buffer =~ s/ob2/$ins2/;
        $buffer =~ s/ob3/$ins3/;
        $buffer =~ s/ob4/$ins4/;
        print "$buffer\n";
      }
    }
  }
}

(Current Output)
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 443

Я могу грубо заставить это, но надеялся на некоторое вдохновение, а не на чрезмерное повторение кода. Я могу написать отдельные циклы для каждого сценария, но надеялся на некоторое вдохновение на более элегантном пути.

(if 3 occurrences of ob#)
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','object-group','ob2','object-group','ob3','eq','53');

foreach $ins1 (@{$OG{ob1}}) {
  foreach $ins2 (@{$OG{ob2}}) {
    foreach $ins3(@{$OG{ob3}}) {
      $buffer = "";
      foreach $element (@line) {
        if($element =~ /object-group/) { next; }
        $buffer = $buffer . ' ' . $element;
      }
      $buffer =~ s/ob1/$ins1/;
      $buffer =~ s/ob2/$ins2/;
      $buffer =~ s/ob3/$ins3/;
      print "$buffer\n";
    }
  }
}

(if 2 occurrences of ob#)
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','host','30.0.0.30','object-group','ob2','eq','23');

foreach $ins1 (@{$OG{ob1}}) {
  foreach $ins2 (@{$OG{ob2}}) {
    $buffer = "";
    foreach $element (@line) {
      if($element =~ /object-group/) { next; }
      $buffer = $buffer . ' ' . $element;
    }
    $buffer =~ s/ob1/$ins1/;
    $buffer =~ s/ob2/$ins2/;
    print "$buffer\n";
  }
}

(if 1 occurrence of ob#)
# @line = ('access-list','vlan_in','extended','permit','tcp','host','40.0.0.10','object-group','ob1','eq 80');

foreach $ins1 (@{$OG{ob1}}) {
  $buffer = "";
  foreach $element (@line) {
    if($element =~ /object-group/) { next; }
    $buffer = $buffer . ' ' . $element;
  }
  $buffer =~ s/ob1/$ins1/;
  print "$buffer\n";
}

1 Ответ

0 голосов
/ 15 января 2019

То, что вы ищете, является перекрестным произведением значений в %OG. CPAN на помощь. Следующий код использует Set :: Product для создания перекрестных продуктов.

use Set::Product qw[ product ];

my @line = (
    'access-list',  'vlan_in', 'extended',     'permit',
    'object-group', 'ob1',     'object-group', 'ob2',
    'object-group', 'ob3',     'object-group', 'ob4'
);

# same order as things fed to product
my @placeholders = qw[ ob1 ob2 ob3 ob4 ];

product {
    # for efficiency, this should be done outside of this loop
    my $buffer = join( ' ', grep { !/object-group/ } @line );

    # product places the values in @_; shift them off in order
    $buffer =~ s/$_/shift()/ge for @placeholders;

    print $buffer . "\n";
}
  [ 'tcp',         'udp' ],
  [ '10.0.0.10', '10.0.0.20' ],
  [ '20.0.0.15', '20.0.0.25' ],
  [ 'eq 22',     'eq 443' ]
;

, что приводит к

access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 443
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...