xmlstarlet - необходимо выборочно заменить значение атрибута на основе значения другого атрибута

Просто интересно, может ли кто-нибудь мне помочь. В настоящее время я создаю брандмауэр pfsense, который использует VPN-подключения для защиты трафика. Поставщик VPN предоставляет механизм переадресации портов, но номер входящего порта меняется каждый час. У меня есть скрипт, который позволяет мне обнаруживать новый порт, но мне нужен скриптовый способ изменить настройки перенаправления портов в брандмауэре, чтобы они соответствовали.

Фрагмент файла конфигурации брандмауэра, который управляет этим, выглядит следующим образом:

<?xml version="1.0"?>
<pfsense>
  <nat>
                <rule>
                        <source>
                                <any/>
                        </source>
                        <destination>
                                <any/>
                                <port>53400</port>
                        </destination>
                        <protocol>tcp/udp</protocol>
                        <target>192.168.0.15</target>
                        <local-port>53400</local-port>
                        <interface>opt2</interface>
                        <descr><![CDATA[Torrent]]></descr>
                        <associated-rule-id>nat_52d81d2dc904f5.77023355</associated-rule-id>
                        <created>
                                <time>1389894957</time>
                                <username>[email protected]</username>
                        </created>
                        <updated>
                                <time>1389980696</time>
                                <username>[email protected]</username>
                        </updated>
                </rule>
  </nat>

  <filter>
                <rule>
                        <id/>
                        <type>pass</type>
                        <interface>opt2</interface>
                        <ipprotocol>inet</ipprotocol>
                        <tag/>
                        <tagged/>
                        <max/>
                        <max-src-nodes/>
                        <max-src-conn/>
                        <max-src-states/>
                        <statetimeout/>
                        <statetype>keep state</statetype>
                        <os/>
                        <protocol>tcp/udp</protocol>
                        <source>
                                <any/>
                        </source>
                        <destination>
                                <address>192.168.0.15</address>
                                <port>53400</port>
                        </destination>
                        <log/>
                        <descr><![CDATA[NAT Torrent]]></descr>
                        <associated-rule-id>nat_52d81d2dc904f5.77023355</associated-rule-id>
                        <created>
                                <time>1389894957</time>
                                <username>NAT Port Forward</username>
                        </created>
                        <updated>
                                <time>1389899075</time>
                                <username>[email protected]</username>
                        </updated>
               </rule>
  </filter>
</pfsense>

В приведенном выше XML у нас есть две части, которые составляют правило перенаправления портов для pfsense. Часть, заключенная в секцию <nat>, является портом вперед. Раздел в <rule> представляет собой правило входящего брандмауэра для конкретного интерфейса. Оба должны быть изменены, чтобы новая настройка переадресации портов была эффективной.

Я думал использовать xmlstarlet для изменения файла конфигурации, используя <descr> в качестве ключа для определения того, какие разделы нужно изменить.

Я знаю, что у вас могут быть такие данные, как:

<username><![CDATA[name]]></username>
<password><![CDATA[password]]></password>
<dbname><![CDATA[name]]></dbname>

и измените его с помощью:

xml ed -P -O -L \
  -u '//username/text()' -v 'something' \
  -u '//password/text()' -v 'somethingelse' \
  -u '//dbname/text()' -v 'somethingdifferent' file.xml

а также что у вас может быть что-то вроде:

<objects>
 <object>
    <name>Foo</name>
    <constant1>10</constant1>
    <constant2>20</constant2>
  </object>
  <object>
    <name>Bar</name>
    <constant1>15</constant1>
    <constant2>40</constant2>
  </object>
<objects>

и обновить атрибуты с помощью:

xmlstarlet ed -u '//object[name="Foo"]/const1' -v 18 sample.xml

Однако я изо всех сил пытаюсь объединить их, чтобы у меня был один оператор, который соответствует <descr>="Torrent", а затем обновляет соответствующие атрибуты <port> и <local-port>.

Любая помощь с подходящей командой xmlstarlet будет высоко оценена.


person Bagpuss    schedule 18.01.2014    source источник
comment
Является ли использование нескольких утверждений неприемлемым?   -  person npostavs    schedule 18.01.2014
comment
Нисколько. Это будет сценарий bash/sh, поэтому не имеет значения, сколько операторов требуется для достижения желаемого результата. Я буду просто счастлив получить метод, который работает.   -  person Bagpuss    schedule 19.01.2014


Ответы (1)


person    schedule
comment
Спасибо большое. Это работает отлично. Моя ошибка заключалась в том, что я не включил бит /destination. Я просто этого не заметил. - person Bagpuss; 21.01.2014