Скрипт миграции на UTM5

Вопросы по UTM 3.0 и UTM 4.0 (поддержка прекращена)
Закрыто

Вы ещё используете UTM4?

Да, планирую перейти на UTM5
2
33%
Да, планирую перейти на другой биллинг
0
Голосов нет
Да и собираюсь пользоваться в будущем
0
Голосов нет
Нет
4
67%
 
Всего голосов: 6

Аватара пользователя
marvin
Сообщения: 77
Зарегистрирован: Сб мар 24, 2007 11:18
Откуда: Нижняя Тура

Скрипт миграции на UTM5

Сообщение marvin »

Хочу поделиться с сообществом предварительным вариантом скрипта для миграции из UTM4 на UTM5, использующим ourfa-perl.

Он реализует перенос списка классов трафика (требуется исправление ошибки в api.xml), перенос списка тарифов, перенос списка услуг, перенос списка пользователей со статическими и vpn-адресами, а также перенос базы карточек оплаты.

Он не реализует перенос групп пользователей, в связи с отсутствием поддержки повышенных привилегий несистемных пользователей в UTM5, а так-же ряда других данных.

Он реализует лишь частичное воспроизведение логики UTM4, требует "допиливания" и не предназначен для сдачи системы "под ключ" :)

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

utm5_import.pl

Код: Выделить всё

#!/usr/bin/perl

use Mysql;
use Ourfa;
use Socket;
use Net::Netmask;

$prefix="/netup";                                                                                                                               # путь к файлу конфигурации UTM4
open &#40;CONFIG, "$prefix/utm/utm.cfg"&#41;; @config = <CONFIG>; close &#40;CONFIG&#41;;
foreach $line &#40;@config&#41; &#123;
  if &#40;$line =~ m/^&#40;&#91;^#&#93;.+?&#41;=&#40;.*&#41;$/&#41; &#123;
      $$1 = $2;
    &#125;;
&#125;;

$dbh = Mysql->connect&#40;$database_host,$database,$database_login,$database_password&#41;; $dbh->Query&#40;"SET NAMES utf8"&#41;;                              # подключение к базе UTM

my $ourfa = Ourfa->new&#40;                                                                                                                         # подключение к ядру UTM5 по протоколу URFA
      api_xml_dir => "/netup/utm5/xml",
      server => 'localhost',
      login => $ENV&#123;OURFA_LOGIN&#125; || 'init',
      password => $ENV&#123;OURFA_PASSWORD&#125; || 'init',
      ssl_cert => '/netup/utm5/admin.crt',
      ssl_key  => '/netup/utm5/admin.crt',
      ssl => 'rsa_cert'
    &#41;;

$services = $ourfa->rpcf_get_services_list&#40;&#41;; if&#40;$services->&#123;services_count&#125;>0&#41;&#123; die "This script intended to work on clean systems only.\n"; &#125; # проверка отсутствия услуг, работаем только на чистой системе

#==============================================================================================================================================================================================================================================

$result = $ourfa->rpcf_get_tclasses&#40;&#41;; foreach my $tcls &#40;@&#123;$result->&#123;'array-1'&#125;&#125;&#41;&#123; $ourfa->rpcf_remove_tclass&#40;tclass_id=>$tcls->&#123;tclass_id&#125;&#41;; &#125; # удаление существующих классов трафика

$sth1 = $dbh->query&#40;"SELECT * FROM traffic_classes WHERE tag LIKE 'name'"&#41;;                                                                     # получение списка названий классов

while&#40;my %tclass1 = $sth1->fetchhash&#41;&#123;

    my @list;
    my $display = 0;
    my $graph = 0;
    my $graph_color = 0;
    my $class_id = $tclass1&#123;cid&#125;;
    my $tclass_name = $tclass1&#123;value&#125;; print "tclass&#58; $tclass_name\n";

    $sth2 = $dbh->query&#40;"SELECT value FROM traffic_classes WHERE cid = $class_id AND tag LIKE 'graph'"&#41;;                                        # выборка атрибута заливки/отображения &#40;заливка не работает&#41;
        if&#40;my %tclass2 = $sth2->fetchhash&#41;&#123; $graph = 1-$tclass2&#123;value&#125;; $display = 1; &#125; else &#123; $graph = 0; $display = 0; &#125;

    $sth2 = $dbh->query&#40;"SELECT value FROM traffic_classes WHERE cid = $class_id AND tag LIKE 'graph_color'"&#41;;                                  # выборка цвета кривой
        if&#40;my %tclass2 = $sth2->fetchhash&#41;&#123; $graph_color = $tclass2&#123;value&#125;; &#125;

    $sth2 = $dbh->query&#40;"SELECT * FROM traffic_classes_nets WHERE cid = $class_id"&#41;;                                                            # получение списка подклассов трафика

        while&#40;my %tclass2 = $sth2->fetchhash&#41;&#123;

            push @list, &#123; # построение списка хешей подклассов трафика
                saddr           => inet_aton&#40;$tclass2&#123;ip_from&#125;&#41;,        # ip адрес подсети источника
                saddr_mask      => inet_aton&#40;$tclass2&#123;netmask_from&#125;&#41;,   # маска подсети источника
                daddr           => inet_aton&#40;$tclass2&#123;ip_to&#125;&#41;,          # ip адрес подсети адресата
                daddr_mask      => inet_aton&#40;$tclass2&#123;netmask_to&#125;&#41;,     # маска подсети адресата
                src_as          => inet_aton&#40;$tclass2&#123;src_as&#125;&#41;,         # номер автономной системы источника
                dst_as          => inet_aton&#40;$tclass2&#123;dst_as&#125;&#41;,         # номер автономной системы адресата
                sport           => $tclass2&#123;srcport&#125;,                   # порт источника
                dport           => $tclass2&#123;dstport&#125;,                   # порт назначения
                input           => $tclass2&#123;input&#125;,                     # входящий интерфейс
                output          => $tclass2&#123;output&#125;,                    # исходящий интерфейс
                tcp_flags       => $tclass2&#123;tcp_flags&#125;,                 # флаги протокола TCP
                proto           => $tclass2&#123;prot&#125;,                      # протокол
                tos             => $tclass2&#123;tos&#125;,                       # type of service
                nexthop         => inet_aton&#40;$tclass2&#123;nexthop&#125;&#41;,        # следующий маршрутизатор
                ip_from         => inet_aton&#40;'0.0.0.0'&#41;,                # ip адрес маршрутизатора
                use_src_as      => 0,                                   # не использовать номер АС источника
                use_dst_as      => 0,                                   # не использовать номер АС адресата
                use_sport       => 0,                                   # не использовать порт источника
                use_dport       => 0,                                   # не использовать порт адресата
                use_input       => 0,                                   # не использовать номер входящего интерфейса
                use_output      => 0,                                   # не использовать номер исходящего интерфейса
                use_tcp_flags   => 0,                                   # не использовать флаги TCP
                use_proto       => 0,                                   # не использовать номер протокола
                use_tos         => 0,                                   # не использовать TOS
                use_nexthop     => 0,                                   # не использовать следующий маршрутизатор
                skip            => 0                                    # не пропускать классификацию
            &#125;;
        &#125;;

    my %tclass=&#40;  # подготовка хеша описателя класса трафика
        tclass_id               => $class_id,                           # класс трафика
        tclass_name             => $tclass_name,                        # название класса трафика
        graph_color             => hex $graph_color,                    # цвет кривой на графике
        is_display              => $display,                            # статус отображения кривой
        is_fill                 => $graph,                              # статус заливки &#40;не используется&#41;
        time_range_id           => 0,                                   # номер временной зоны
        dont_save               => 0,                                   # сохранять детальную статистику
        local_traf_policy       => 0,                                   # метод учёта межабонентского траффика &#91;0 -- на получателя&#93;
        tclass_count            => $#list+1,                            # длина списка подклассов
          subclasses            => &#91;@list&#93;                              # список подклассов
    &#41;;

    $ourfa->rpcf_add_tclass2&#40;%tclass&#41;; # запись класса в UTM5

&#125;;

#==============================================================================================================================================================================================================================================

$ourfa->rpcf_add_iptraffic_service_ex&#40; # запись первичной услуги передачи данных, являющейся родителем для дочерних услуг, связанных с тарифными планами

                                                                                # -1 -- шаблон услуги &#40;используется для создания дочерних услуг, связанных с тарифными планами&#41;
    parent_id                   => -1,                                          #  0 -- обычная услуга &#40;может быть подключена непосредственно пользователю&#41;
                                                                                #  n -- номер родительской услуги &#40;шаблона&#41; при связывании с тарифным планом

    tariff_id                   => 0,                                           # номер родительского тарифного плана
    service_name                => 'Передача данных',                           # описание услуги
    comment                     => 'корневая услуга',                           # комментарий
    link_by_default             => 0,                                           # 1 -- подключать по умолчанию при добавлении тарифа &#40;в интерфейсе администратора&#41;
    is_dynamic                  => 0,                                           # 1 -- использование динамических адресов
    cost                        => 0,                                           # периодическая составлющая стоимости
    discount_method             => 3,                                           # метод списания &#40;1 -- в начале; 2 -- в конце; 3 -- в течение всего учётного периода&#41;
    null_service_prepaid        => 0,                                           # 1 -- обнуление предоплаченного трафика
    num_of_borders              => 0,
    num_of_prepaid              => 0,
    num_of_groups               => 0
&#41;;

$sth1 = $dbh->query&#40;"SELECT * FROM products_services"&#41;; # импорт тарифных планов

while&#40;my %utm_product = $sth1->fetchhash&#41;&#123;

    my $root_service = $ourfa->rpcf_add_periodic_service_ex&#40; # запись услуг абонентской платы, являющихся родителями для дочерних услуг, связанных с тарифными планами
                                                                                # -1 -- шаблон услуги &#40;используется для создания дочерних услуг, связанных с тарифными планами&#41;
        parent_id               => -1,                                          #  0 -- обычная услуга &#40;может быть подключена непосредственно пользователю&#41;
                                                                                #  n -- номер родительской услуги &#40;шаблона&#41; при связывании с тарифным планом
        tariff_id               => 0,                                           # номер родительского тарифного плана
        service_name            => $utm_product&#123;prod_name&#125;,                     # описание услуги
        comment                 => 'периодическая услуга',                      # комментарий
        link_by_default         => 0,                                           # 1 -- подключать по умолчанию при добавлении тарифа &#40;в интерфейсе администратора&#41;
        cost                    => $utm_product&#123;price&#125;,                         # периодическая составлющая стоимости
        discount_method         => 3                                            # метод списания &#40;1 -- в начале; 2 -- в конце; 3 -- в течение всего учётного периода&#41;

    &#41;;

    %new_product_id = &#40;%new_product_id, $utm_product&#123;id&#125; => $root_service->&#123;service_id&#125;&#41;;   # построение ассоциативного массива старый_product_id->новый_product_id

&#125;;

$sth1 = $dbh->query&#40;"SELECT * FROM tariffs_current"&#41;; # импорт тарифных планов

while&#40;my %utm = $sth1->fetchhash&#41;&#123;

    my $tariff = $ourfa->rpcf_add_tariff_new&#40; # запись тарифных планов
        name                    => $utm&#123;name&#125;,                                  # название тарифа
        balance_rollover        => $utm&#123;endperiod_zeroing_balance&#125;,             # 1 -- обнуление счёта в конце учётного периода
        comments                => ''                                           # комментарии
    &#41;;

    %new_tp = &#40;%new_tp, $utm&#123;tid&#125; => $tariff->&#123;tp_id&#125;&#41;;   # построение ассоциативного массива старый_tariff_id->новый_tariff_id

    print "tariff&#58; $utm&#123;name&#125;\n";

    my @borders_list; $sth2 = $dbh->query&#40;"SELECT * FROM tariff_traffic_borders WHERE tid = $utm&#123;tid&#125;"&#41;; # импорт границ тарификации трафика

    while&#40;my %utm_traffic_borders = $sth2->fetchhash&#41;&#123;
        push @borders_list, &#123;tclass_b => $utm_traffic_borders&#123;tc_id&#125;, size_b => $utm_traffic_borders&#123;border&#125;, cost_b => $utm_traffic_borders&#123;cost&#125;&#125;;
    &#125;;

    $ourfa->rpcf_add_service_to_tariff&#40;   # запись услуг передачи данных, связанных с тарифными планами
        parent_id               => 1,                                           # родительская услуга-шаблон 'Передача данных'
        tariff_id               => $tariff->&#123;tp_id&#125;,                            # номер тарифного плана
        service_name            => 'Аренда IP адреса',                          # название услуги
        service_type            => 3,                                           # тип услуги &#91;3 -- 'передача IP-трафика'&#93;
        comment                 => '',                                          # комментарий
        link_by_default         => 1,                                           # подключать по умолчанию
        is_dynamic              => 0,                                           # не использовать динамические адреса
        cost                    => 0,                                           # стоимость
        periodic_type           => 0,                                           # периодичность списания &#40;не используется&#41;
        discount_method         => 3,                                           # метод списания &#91;3 -- в течение всего учётного периода&#93;
        null_service_prepaid    => 0,                                           # не обнулять предоплаченный трафик
        num_of_borders          => $#borders_list+1,                            # число границ тарификации для &#91;платного&#93; трафика
          borders_list          => &#91;@borders_list&#93;,                             # список границ тарификации трафика
        num_of_prepaid          => 0,
        num_of_groups           => 0
    &#41;;

    $sth2 = $dbh->query&#40; # Внимание! cost >= price !
        "SELECT products_services_tariffs.prod_code as prod_code, products_services.prod_name as name, products_services.is_periodic as is_periodic, products_services.discount_at_begin as discount_at_begin,
                products_services.recalc_prod_infact as recalc_prod_infact, products_services.price * products_services_tariffs.qnt as cost
            FROM tariffs_current, products_services_tariffs, products_services
            WHERE tariffs_current.tid = products_services_tariffs.tariff_id AND products_services_tariffs.prod_code = products_services.id AND products_services_tariffs.tariff_id = $utm&#123;tid&#125;"
    &#41;;

    while&#40;my %utm_periodics = $sth2->fetchhash&#41;&#123;
        $ourfa->rpcf_add_service_to_tariff&#40;  # запись периодических услуг &#40;абонентской платы&#41;, связанных с тарифными планами
            parent_id           => $new_product_id&#123;$utm_periodics&#123;prod_code&#125;&#125;,  # родительская услуга-шаблон
            tariff_id           => $tariff->&#123;tp_id&#125;,                            # номер тарифного плана
            service_name        => $utm_periodics&#123;name&#125;,                        # название услуги
            service_type        => $utm_periodics&#123;is_periodic&#125;+1,               # тип услуги &#91;1 -- разовая услуга, 2 -- периодическая услуга&#93;
            comment             => '',                                          # комментарий
            link_by_default     => 1,                                           # подключать по умолчанию
            is_dynamic          => 0,                                           # не использовать динамические адреса
            cost                => $utm_periodics&#123;cost&#125;,                        # стоимость
            periodic_type       => 0,                                           # периодичность списания &#40;не используется&#41;
            discount_method     => 3-2*$utm_periodics&#123;discount_at_begin&#125;        # метод списания &#91;1 -- в начале учётного периода; 3 -- в течение всего учётного периода&#93;
        &#41;;
    &#125;;
&#125;;

#==============================================================================================================================================================================================================================================

$search = $ourfa->rpcf_search_users_new&#40;  # получение списка существующих пользователей
    poles_count                 => 1,                                           # длина списка возвращаемых полей
      poles                     => &#91;&#123;pole_code_array=>2&#125;&#93;,                      # список возвращаемых полей &#40;2 -- 'login'&#41;
    select_type                 => 1,
    patterns_count              => 1,                                           # длина списка шаблонов поиска
      patterns                  => &#91;&#123;what_id=>2, criteria_id=>1, pattern=>''&#125;&#93;  # список полей &#40;2 -- 'login'&#41;, критериев &#40;1 -- 'LIKE'&#41; и образцов для поиска
&#41;;

for&#40;my $i = 0; $i < $search->&#123;user_data_size&#125;; $i++&#41;&#123; %exist_users = &#40;%exist_users, @&#123;$search->&#123;'array-1'&#125;&#125;&#91;$i&#93;->&#123;login&#125; => @&#123;$search->&#123;'array-1'&#125;&#125;&#91;$i&#93;->&#123;user_id&#125;&#41;; &#125;; # построение ассоциативного массива логин->идентификатор

$sth = $dbh->query&#40;"SELECT * FROM users"&#41;; # импорт списка пользователей UTM

while&#40;my %utm = $sth->fetchhash&#41;&#123; my $ip_service_id; my @ip_groups; $count++; $login=lc&#40;$utm&#123;login&#125;&#41;; print "user&#58; $login\n";

    if&#40;! defined $exist_users&#123;$login&#125;&#41;&#123; # проверка отсутствия добавляемого пользователя в базе UTM5

        my $user = $ourfa->rpcf_add_user&#40;                                   # добавление пользователя
            login               => $login,                                      # login
            password            => $utm&#123;password&#125;,                              # пароль доступа
            full_name           => $utm&#123;full_name&#125;,                             # полное имя
            comments            => $utm&#123;comments&#125;,                              # комментарии
            email               => $utm&#123;email&#125;,                                 # адрес электронной почты
            is_juridical        => $utm&#123;is_juridical&#125;,                          # статус юридического лица
            act_address         => $utm&#123;actual_address&#125;,                        # фактический адрес
            jur_address         => $utm&#123;juridical_address&#125;,                     # юридический адрес
            tax_number          => $utm&#123;tax_number&#125;                             # ИНН
        &#41;;

        my $account = $ourfa->rpcf_add_account&#40;                             # добавление учётной записи
            user_id             => $user->&#123;user_id&#125;,                            # идентификатор пользователя
            balance             => $utm&#123;bill&#125;,                                  # баланс
            credit              => $utm&#123;credit&#125;,                                # кредит
            is_blocked          => $utm&#123;block&#125;,                                 # статус блокировки
            int_status          => $utm&#123;fw_on&#125;                                  # статус доступа в интернет
        &#41;;

        my $discount_period = $ourfa->rpcf_add_discount_period_return&#40;      # добавление учётного периода
            periodic_type       => 1048576,                                     # &#91;1048576 -- другая длина&#93;
            start_date          => $utm&#123;ab_pstart&#125;,                             # начало периода
            expire_date         => $utm&#123;ab_pend&#125;,                               # окончание периода
            custom_duration     => $utm&#123;ab_pend&#125;-$utm&#123;ab_pstart&#125;,               # длительность периода
            discount_interval   => 168                                          # число списаний в неделю &#91;168 -- каждый час&#93; !!!FIXME!!!
        &#41;;

        my $tariff_link = $ourfa->rpcf_link_user_tariff&#40;                    # подключение пользователю тарифного плана
            user_id             => $user->&#123;user_id&#125;,                            # идентификатор пользователя
            account_id          => $account->&#123;account_id&#125;,                      # номер учётной записи &#40;в общем случае у одного пользователя может быть несколько учётных записей&#41;
            tariff_current      => $new_tp&#123;$utm&#123;tariff&#125;&#125;,                       # текущий тарифный план
            tariff_next         => $new_tp&#123;$utm&#123;tariff_next&#125;&#125;,                  # тарифный план следующего учётного периода
            discount_period_id  => $discount_period->&#123;discount_period_id&#125;,      # номер учётного периода
            tariff_link_id      => 0                                            # номер тарифной связки
        &#41;;

        my $tariff = $ourfa->rpcf_get_tariff&#40;tariff_id => $new_tp&#123;$utm&#123;tariff&#125;&#125;&#41;; # получение списка услуг, связанных с текущим тарифом

        for&#40;my $i = 0; $i < $tariff->&#123;services_count&#125;; $i++&#41;&#123;

            if&#40;@&#123;$tariff->&#123;'array-1'&#125;&#125;&#91;$i&#93;->&#123;service_type_array&#125; == 2&#41;&#123;     # получение периодических услуг

                my %new_service_link = &#40;
                       user_id            => $user->&#123;user_id&#125;,                                  # идентификатор пользователя
                       account_id         => $account->&#123;account_id&#125;,                            # номер учётной записи
                       service_id         => @&#123;$tariff->&#123;'array-1'&#125;&#125;&#91;$i&#93;->&#123;service_id_array&#125;,   # номер услуги
                       service_type       => 2,                                                 # тип услуги &#91;2 -- периодическая услуга&#93;
                       tariff_link_id     => $tariff_link->&#123;tariff_link_id&#125;,                    # номер тарифной связки
                       slink_id           => 0,                                                 # номер сервисной связки
                       is_blocked         => 0,                                                 # статус блокировки
                       discount_period_id => $discount_period->&#123;discount_period_id&#125;,            # номер учётного периода
#                       start_date         => $utm&#123;ab_pstart&#125;,                                   # начало действия услуги       !!!FIXME!!!
#                       expire_date        => $utm&#123;ab_pend&#125;,                                     # окончание действия услуги    !!!FIXME!!!
                       unabon             => 1,                                                 # пересчёт абонентской платы &#40;необходимо для корректного переноса суммы&#41;
                       unprepay           => 1                                                  # пересчёт предоплаченных услуг
                    &#41;;

                eval&#123; # перехват ошибок
                    $ourfa->rpcf_add_service_to_user&#40;%new_service_link&#41;;    # запись периодических услуг пользователю
                &#125;;

            &#125;; if&#40;@&#123;$tariff->&#123;'array-1'&#125;&#125;&#91;$i&#93;->&#123;service_type_array&#125; == 3&#41;&#123; $ip_service_id = @&#123;$tariff->&#123;'array-1'&#125;&#125;&#91;$i&#93;->&#123;service_id_array&#125; &#125;;  # получение id услуги передачи ip трафика

        &#125;;

        my %new_service_link = &#40;
           user_id            => $user->&#123;user_id&#125;,                              # идентификатор пользователя
           account_id         => $account->&#123;account_id&#125;,                        # номер учётной записи
           service_id         => $ip_service_id,                                # номер услуги
           service_type       => 3,                                             # тип услуги &#91;3 -- передача IP траффика&#93;
           tariff_link_id     => $tariff_link->&#123;tariff_link_id&#125;,                # номер тарифной связки
           slink_id           => 0,                                             # номер сервисной связки
           is_blocked         => 0,                                             # статус блокировки
           discount_period_id => $discount_period->&#123;discount_period_id&#125;,        # номер учётного периода
#           start_date         => $utm&#123;ab_pstart&#125;,                               # начало действия услуги       !!!FIXME!!!
#           expire_date        => $utm&#123;ab_pend&#125;,                                 # окончание действия услуги    !!!FIXME!!!
           unabon             => 1,                                             # пересчёт абонентской платы
           unprepay           => 1                                              # пересчёт предоплаченных услуг
        &#41;;

        my @utm_net = split&#40;' ', $utm&#123;ip&#125;&#41;;                                     # разбор списка статических IP-адресов
            foreach $net &#40;@utm_net&#41;&#123; my $block = new Net&#58;&#58;Netmask &#40;$net&#41;;       # добавление в список не-VPN адресов
                push @ip_groups, &#123;
                    ip_address            => inet_aton&#40;$block->base&#40;&#41;&#41;,         # ip адрес
                    mask                  => inet_aton&#40;$block->mask&#40;&#41;&#41;,         # маска ip адреса
                    iptraffic_login       => '',                                # login
                    iptraffic_password    => '',                                # пароль
                    ip_not_vpn            => 1,                                 # тип адреса &#91;1 -- не VPN&#93;
                    dont_use_fw           => 0                                  # применять правила firewall
                &#125;;
            &#125;;

        $sth2 = $dbh->query&#40;"SELECT * FROM ip_addr WHERE uid = $utm&#123;id&#125;"&#41;;      # получение списка VPN адресов
            while&#40;my %vpn = $sth2->fetch_hash&#41;&#123;                                 # добавление в список VPN адресов
                push @ip_groups, &#123;
                    ip_address            => inet_aton&#40;$vpn&#123;ip_addr&#125;&#41;,          # ip адрес
                    mask                  => inet_aton&#40;$vpn&#123;netmask&#125;&#41;,          # маска ip адреса
                    iptraffic_login       => '',                                # login
                    iptraffic_password    => '',                                # пароль
                    ip_not_vpn            => 0,                                 # тип адреса &#91;0 -- VPN&#93;
                    dont_use_fw           => 1                                  # не применять правила firewall
                &#125;;
            &#125;;

        eval&#123; # экранирование ошибок
            if&#40;$#ip_groups>=0&#41;&#123; # запись ip адресов пользователю
                $ourfa->rpcf_add_service_to_user&#40;%new_service_link, ip_groups_list => &#91;@ip_groups&#93;&#41;;
            &#125;;
        &#125;;

        $ourfa->rpcf_save_account&#40; # дополнение учётной записи
            account_id              => $account->&#123;account_id&#125;,                  # номер учётной записи
            discount_period_id      => $discount_period->&#123;discount_period_id&#125;,  # номер учётного периода
            credit                  => $utm&#123;credit&#125;,                            # кредит
            is_blocked              => $utm&#123;block&#125;,                             # статус блокировки                                             !!!FIXME!!!
            dealer_account_id       => 0,                                       # номер учётной записи дилера
            vat_rate                => 0,                                       # НДС
            sale_tax_rate           => 0,                                       # НСП
            int_status              => $utm&#123;fw_on&#125;,                             # статус доступа в интернет
            block_recalc_abon       => 0,                                       # пересчитывать абонентскую плату при системной блокировке      !!!FIXME!!!
            block_recalc_prepaid    => 0,                                       # пересчитывать предоплаченные услуги при системной блокировке  !!!FIXME!!!
            unlimited               => $utm&#123;discount_eq&#125;
        &#41;;

    &#125; else &#123; print "Modifying of existing users are not implemented...\n"; &#125;

&#125;;

#==============================================================================================================================================================================================================================================

$sth = $dbh->query&#40;"SELECT * FROM icards"&#41;; # импорт базы карт оплаты

while&#40;my %card = $sth->fetchhash&#41;&#123;

    $ourfa->rpcf_card_add&#40;
        secret                  => $card&#123;card_serial&#125;,                          # секретный код
        balance                 => $card&#123;card_nominal&#125;,                         # номинал карты
        currency                => 810,                                         # валюта&#58; российские рубли
        expire                  => $card&#123;card_expire_date&#125;,                     # срок действия карты
        days                    => 0,
        is_used                 => 1-$card&#123;card_status&#125;,                        # статус активации карты
        tp_id                   => 0                                            # 0 -- применима на любом тарифном плане
    &#41;;

&#125;;
P.S. Надеюсь, кому-то поможет "въехать" в логику пятой версии и обойти несколько подводных камней.

Аватара пользователя
marvin
Сообщения: 77
Зарегистрирован: Сб мар 24, 2007 11:18
Откуда: Нижняя Тура

Сообщение marvin »

А сейчас немного юмора: скрипт для обратной миграции части данных из базы UTM5 в базу UTM4 :D

Код: Выделить всё

#!/usr/bin/perl

use Mysql;
$prefix="/netup"; @force=grep &#123;/--force/&#125; @ARGV;
open &#40;CONFIG, "$prefix/utm5/utm5.cfg"&#41;; @config = <CONFIG>; close &#40;CONFIG&#41;; foreach $line &#40;@config&#41; &#123; if &#40;$line =~ m/^&#40;&#91;^#&#93;.+?&#41;=&#40;.*&#41;$/&#41; &#123; $$1 = $2; &#125;; &#125;;
    $database5_host=$database_host; $database5=$database; $database5_login=$database_login; $database5_password=$database_password; $database5_port=$database_port;
open &#40;CONFIG, "$prefix/utm/utm.cfg"&#41;; @config = <CONFIG>; close &#40;CONFIG&#41;; foreach $line &#40;@config&#41; &#123; if &#40;$line =~ m/^&#40;&#91;^#&#93;.+?&#41;=&#40;.*&#41;$/&#41; &#123; $$1 = $2; &#125;; &#125;;

$dblocal  = Mysql->connect&#40;$database5_host,$database5,$database5_login,$database5_password&#41;; $dblocal ->Query&#40;"SET NAMES cp1251"&#41;;
$dbremote = Mysql->connect&#40;$database_host, $database, $database_login, $database_password&#41;;  $dbremote->Query&#40;"SET NAMES cp1251"&#41;;

create_remote_users&#40;&#41;; create_remote_user_log&#40;&#41;; create_remote_ipaddr&#40;&#41;; create_remote_ipaddr_used&#40;&#41;; create_remote_tariffs_current&#40;&#41;; create_freeradius_tables&#40;&#41;; create_radius_packets_accounting&#40;&#41;;

$stlocal  = $dblocal->query&#40;"SELECT max&#40;change_date&#41; FROM tariffs WHERE is_deleted=0"&#41;   or die $Mysql&#58;&#58;db_errstr; %foo = $stlocal->fetchhash;  if&#40;$foo&#123;'max&#40;change_date&#41;'&#125;==''&#41;&#123;$local_date=0;&#125;;  $local_date  = $foo&#123;'max&#40;change_date&#41;'&#125;;
$stremote = $dbremote->query&#40;"SELECT max&#40;change_date&#41; FROM tariffs_current"&#41;             or die $Mysql&#58;&#58;db_errstr; %bar = $stremote->fetchhash; if&#40;$bar&#123;'max&#40;change_date&#41;'&#125;==''&#41;&#123;$remote_date=0;&#125;; $remote_date = $bar&#123;'max&#40;change_date&#41;'&#125;;
if&#40;$local_date > $remote_date or $#force > -1&#41;&#123; copy_tariffs&#40;&#41;; print "shadow tariff names list updated\n"; &#125;

$stlocal  = $dblocal->query&#40;"SELECT max&#40;id&#41; FROM user_log"&#41;                              or die $Mysql&#58;&#58;db_errstr; %foo = $stlocal->fetchhash;  if&#40;$foo&#123;'max&#40;id&#41;'&#125;==''&#41;&#123;$local_id=0;&#125;;  $local_id  = $foo&#123;'max&#40;id&#41;'&#125;;
$stremote = $dbremote->query&#40;"SELECT max&#40;id&#41; FROM user_log"&#41;                             or die $Mysql&#58;&#58;db_errstr; %bar = $stremote->fetchhash; if&#40;$bar&#123;'max&#40;id&#41;'&#125;==''&#41;&#123;$remote_id=0;&#125;; $remote_id = $bar&#123;'max&#40;id&#41;'&#125;;
if&#40;$local_id > $remote_id or $#force > -1&#41;&#123; copy_user_log&#40;&#41;; copy_users&#40;&#41;; print "shadow users database updated\n"; &#125;

$stlocal  = $dblocal->query&#40;"SELECT max&#40;create_date&#41; FROM ip_groups WHERE is_deleted=0"&#41; or die $Mysql&#58;&#58;db_errstr; %foo = $stlocal->fetchhash;  if&#40;$foo&#123;'max&#40;create_date&#41;'&#125;==''&#41;&#123;$local_date=0;&#125;;  $local_date  = $foo&#123;'max&#40;create_date&#41;'&#125;;
$stremote = $dbremote->query&#40;"SELECT max&#40;reg_date&#41; FROM ip_addr"&#41;                        or die $Mysql&#58;&#58;db_errstr; %bar = $stremote->fetchhash; if&#40;$bar&#123;'max&#40;reg_date&#41;'&#125;   ==''&#41;&#123;$remote_date=0;&#125;; $remote_date = $bar&#123;'max&#40;reg_date&#41;'&#125;;
if&#40;$local_date > $remote_date or $#force > -1&#41;&#123; copy_ipaddr&#40;&#41;; print "shadow ip address database updated\n"; &#125;

###############################################################################################################################################################################################################################################

sub copy_tariffs &#123;
  $stlocal = $dblocal->query&#40;"SELECT * FROM tariffs"&#41; or die $Mysql&#58;&#58;db_errstr;
  $stremote = $dbremote->query&#40;"TRUNCATE TABLE tariffs_current"&#41; or die $Mysql&#58;&#58;db_errstr;
  while &#40;%tariffs = $stlocal->fetchhash&#41;&#123; $dbremote->query&#40;"INSERT INTO tariffs_current
    SET tid = $tariffs&#123;id&#125;,
    change_date = $tariffs&#123;change_date&#125;,
    name = '$tariffs&#123;name&#125;'"&#41; or die $Mysql&#58;&#58;db_errstr;
  &#125;
&#125;

sub copy_users &#123;
  $stlocal = $dblocal->query&#40;"SELECT users.id,
    users.login,
    users.password,
    users.full_name,
    GROUP_CONCAT&#40;INET_NTOA&#40;ip_groups.ip & 4294967295&#41; SEPARATOR ' '&#41; AS ip,
    accounts.balance+0.0001 AS bill,
    accounts.credit,
    accounts.is_blocked AS block,
    users.comments,
    users.create_date AS reg_date,
    users.email,
    discount_periods.start_date AS ab_pstart,
    discount_periods.end_date AS ab_pend,
    account_tariff_link.tariff_id AS tariff,
    account_tariff_link.next_tariff_id AS tariff_next,
    users.is_juridical,
    users.juridical_address,
    users.actual_address,
    accounts.int_status AS fw_on,
    accounts.unlimited AS discount_eq,
    users.is_deleted
    FROM users
    LEFT JOIN users_accounts ON users_accounts.uid = users.id
    LEFT JOIN accounts ON accounts.id = users_accounts.account_id
    LEFT JOIN account_tariff_link ON account_tariff_link.account_id = accounts.id
    LEFT JOIN discount_periods ON discount_periods.id = account_tariff_link.discount_period_id
    LEFT JOIN service_links ON service_links.account_id = accounts.id
    LEFT JOIN iptraffic_service_links ON iptraffic_service_links.id = service_links.id
    LEFT JOIN ip_groups ON ip_groups.ip_group_id = iptraffic_service_links.ip_group_id
    WHERE &#40;ip_groups.ip IS NULL OR &#40;ip_groups.is_deleted = 0 AND &#40;ip_groups.ip_type & 0x1&#41; = 0x1 AND ip_groups.mask = -1&#41;&#41; AND account_tariff_link.is_deleted = 0
    GROUP BY users.login
    ORDER BY users.id"&#41; or die $Mysql&#58;&#58;db_errstr;

  while &#40;%users = $stlocal->fetchhash&#41;&#123; if&#40;$users&#123;is_deleted&#125;&#41;&#123; $dbremote->query&#40;"DELETE FROM users WHERE users.id = $users&#123;id&#125;"&#41;; &#125;else&#123; if&#40;$users&#123;block&#125;>0&#41;&#123;$users&#123;block&#125;=2;&#125;else&#123;$users&#123;block&#125;=1;&#125;
    $dbremote->query&#40;"REPLACE INTO users
      SET id = $users&#123;id&#125;,
      login = '$users&#123;login&#125;',
      password = '$users&#123;password&#125;',
      full_name = '$users&#123;full_name&#125;',
      ip = '$users&#123;ip&#125;',
      bill = $users&#123;bill&#125;,
      bill_abs = $users&#123;bill&#125;,
      credit = $users&#123;credit&#125;,
      block = $users&#123;block&#125;,
      comments = '$users&#123;comments&#125;',
      reg_date = $users&#123;reg_date&#125;,
      email = '$users&#123;email&#125;',
      ab_pstart = $users&#123;ab_pstart&#125;,
      ab_pend = $users&#123;ab_pend&#125;,
      tariff = $users&#123;tariff&#125;,
      tariff_next = $users&#123;tariff_next&#125;,
      is_juridical = $users&#123;is_juridical&#125;,
      juridical_address = '$users&#123;juridical_address&#125;',
      actual_address = '$users&#123;actual_address&#125;',
      fw_on = $users&#123;fw_on&#125;,
      discount_eq = $users&#123;discount_eq&#125;"&#41; or die $Mysql&#58;&#58;db_errstr;
    &#125;
  &#125;
&#125;

sub copy_ipaddr &#123;
  $stlocal = $dblocal->query&#40;"SELECT ip_groups.id, ip_groups.ip & 4294967295 AS ip_addr, ip_groups.mask & 4294967295 AS netmask, users.id AS uid, ip_groups.create_date AS reg_date, ip_groups.is_deleted
    FROM ip_groups
    LEFT JOIN iptraffic_service_links ON iptraffic_service_links.ip_group_id=ip_groups.ip_group_id
    LEFT JOIN service_links ON service_links.id=iptraffic_service_links.id
    LEFT JOIN accounts ON accounts.id=service_links.account_id
    LEFT JOIN users_accounts ON users_accounts.account_id=accounts.id
    LEFT JOIN users ON users.id=users_accounts.uid
    WHERE ip_groups.ip IS NULL OR &#40;ip_groups.is_deleted = 0 AND &#40;ip_groups.ip_type & 0x1&#41; = 0x0 AND ip_groups.mask = -1&#41;"&#41; or die $Mysql&#58;&#58;db_errstr;

  while &#40;%ip_groups = $stlocal->fetchhash&#41;&#123; if&#40;$ip_groups&#123;is_deleted&#125;&#41;&#123; $dbremote->query&#40;"DELETE FROM ip_addr WHERE users.id = $ip_groups&#123;id&#125;"&#41;; &#125;else&#123;
    $dbremote->query&#40;"REPLACE INTO ip_addr
      SET id = $ip_groups&#123;id&#125;,
      ip_addr = $ip_groups&#123;ip_addr&#125;,
      netmask = $ip_groups&#123;netmask&#125;,
      uid = $ip_groups&#123;uid&#125;,
      reg_date = $ip_groups&#123;reg_date&#125;"&#41; or die $Mysql&#58;&#58;db_errstr;
    &#125;
  &#125;
&#125;

sub copy_user_log &#123;
  $stremote = $dbremote->query&#40;"SELECT max&#40;id&#41; FROM user_log"&#41; or die $Mysql&#58;&#58;db_errstr; %foo = $stremote->fetchhash; if&#40;$foo&#123;'max&#40;id&#41;'&#125;==''&#41;&#123; $max_id=0; &#125; else &#123; $max_id=$foo&#123;'max&#40;id&#41;'&#125;; &#125;
  $stlocal = $dblocal->query&#40;"SELECT * FROM user_log WHERE id > $max_id ORDER BY id"&#41; or die $Mysql&#58;&#58;db_errstr;
  while &#40;%userlog = $stlocal->fetchhash&#41;&#123;
    $dbremote->query&#40;"REPLACE INTO user_log
        SET id  = '$userlog&#123;id&#125;',
        user_id = '$userlog&#123;user_id&#125;',
        date    = '$userlog&#123;date&#125;',
        who     = '$userlog&#123;who&#125;',
        what    = '$userlog&#123;what&#125;',
        comment = \"$userlog&#123;comment&#125;\""&#41; or die $Mysql&#58;&#58;db_errstr;
  &#125;
&#125;

###############################################################################################################################################################################################################################################

sub create_remote_user_log &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `user_log` &#40;
    `id` int&#40;11&#41; NOT NULL auto_increment,
    `user_id` int&#40;11&#41; NOT NULL,
    `date` int&#40;11&#41; NOT NULL,
    `who` int&#40;11&#41; NOT NULL,
    `what` varchar&#40;255&#41; NOT NULL,
    `comment` varchar&#40;255&#41; NOT NULL default '',
  PRIMARY KEY  &#40;`id`&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;

sub create_remote_users &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `users` &#40;
    `id` int&#40;11&#41; NOT NULL auto_increment,
    `login` varchar&#40;20&#41; NOT NULL default '',
    `password` varchar&#40;16&#41; default NULL,
    `full_name` varchar&#40;60&#41; NOT NULL default '',
    `ip` text NOT NULL,
    `bill` double NOT NULL default '0',
    `bill_abs` double NOT NULL default '0',
    `credit` float default NULL,
    `block` enum&#40;'0','1'&#41; NOT NULL default '0',
    `comments` text,
    `reg_date` int&#40;11&#41; NOT NULL default '0',
    `priv_level` int&#40;11&#41; NOT NULL default '0',
    `sys_message` text,
    `ip_type` int&#40;11&#41; default NULL,
    `email` varchar&#40;60&#41; default NULL,
    `ab_pstart` int&#40;10&#41; unsigned NOT NULL default '0',
    `ab_pend` int&#40;10&#41; unsigned NOT NULL default '0',
    `ab_ldiscount` int&#40;10&#41; unsigned NOT NULL default '0',
    `lang` varchar&#40;20&#41; NOT NULL default '',
    `tariff` int&#40;10&#41; unsigned NOT NULL default '0',
    `tariff_next` int&#40;10&#41; unsigned NOT NULL default '0',
    `auth_req` int&#40;10&#41; unsigned NOT NULL default '0',
    `discount_eq` int&#40;10&#41; unsigned NOT NULL default '0',
    `is_juridical` int&#40;10&#41; unsigned NOT NULL default '0',
    `juridical_address` text NOT NULL,
    `actual_address` text NOT NULL,
    `tax_number` text NOT NULL,
    `current_bank_account` text NOT NULL,
    `bank_name` text NOT NULL,
    `bank_account` text NOT NULL,
    `bank_bic` text NOT NULL,
    `start_page` varchar&#40;255&#41; NOT NULL default '',
    `mac` varchar&#40;255&#41; NOT NULL default '',
    `fw_on` int&#40;10&#41; unsigned NOT NULL default '0',
    `contract` varchar&#40;255&#41; NOT NULL default '',
    `qnt` double default NULL,
    `radius_attr` text NOT NULL,
  PRIMARY KEY  &#40;`id`&#41;,
  KEY `id` &#40;`id`&#41;,
  KEY `ids` &#40;`id`&#41;,
  KEY `id_2` &#40;`id`,`login`&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;

sub create_remote_users_history &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `users_history` &#40;
    `login` varchar&#40;20&#41; NOT NULL default '',
    `password` varchar&#40;16&#41; default NULL,
    `full_name` varchar&#40;60&#41; NOT NULL default '',
    `ip` text NOT NULL,
    `bill` double NOT NULL default '0',
    `bill_abs` double NOT NULL default '0',
    `credit` float default NULL,
    `block` enum&#40;'0','1'&#41; NOT NULL default '0',
    `comments` text,
    `reg_date` int&#40;11&#41; NOT NULL default '0',
    `priv_level` int&#40;11&#41; NOT NULL default '0',
    `sys_message` text,
    `ip_type` int&#40;11&#41; default NULL,
    `email` varchar&#40;60&#41; default NULL,
    `ab_pstart` int&#40;10&#41; unsigned NOT NULL default '0',
    `ab_pend` int&#40;10&#41; unsigned NOT NULL default '0',
    `ab_ldiscount` int&#40;10&#41; unsigned NOT NULL default '0',
    `lang` varchar&#40;20&#41; NOT NULL default '',
    `tariff` int&#40;10&#41; unsigned NOT NULL default '0',
    `tariff_next` int&#40;10&#41; unsigned NOT NULL default '0',
    `auth_req` int&#40;10&#41; unsigned NOT NULL default '0',
    `discount_eq` int&#40;10&#41; unsigned NOT NULL default '0',
    `is_juridical` int&#40;10&#41; unsigned NOT NULL default '0',
    `juridical_address` text NOT NULL,
    `actual_address` text NOT NULL,
    `tax_number` text NOT NULL,
    `current_bank_account` text NOT NULL,
    `bank_name` text NOT NULL,
    `bank_account` text NOT NULL,
    `bank_bic` text NOT NULL,
    `start_page` varchar&#40;255&#41; NOT NULL default '',
    `mac` varchar&#40;255&#41; NOT NULL default '',
    `fw_on` int&#40;10&#41; unsigned NOT NULL default '0',
    `contract` varchar&#40;255&#41; NOT NULL default '',
    `change_date` int&#40;11&#41; NOT NULL default '0',
    `is_deleted` int&#40;11&#41; NOT NULL default '0',
    `id` int&#40;10&#41; unsigned NOT NULL default '0',
    `rid` int&#40;10&#41; unsigned NOT NULL auto_increment,
  PRIMARY KEY  &#40;`rid`&#41;,
  KEY `id_2` &#40;`login`&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;

sub create_remote_ipaddr &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `ip_addr` &#40;
    `id` int&#40;10&#41; unsigned NOT NULL auto_increment,
    `ip_addr` int&#40;10&#41; unsigned default '0',
    `netmask` int&#40;10&#41; unsigned default '0',
    `uid` int&#40;10&#41; unsigned default '0',
    `reg_date` int&#40;10&#41; unsigned default '0',
    `is_gid` int&#40;10&#41; unsigned NOT NULL default '0',
  PRIMARY KEY  &#40;`id`&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251 PACK_KEYS=0;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;

sub create_remote_ipaddr_used &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `ip_addr_used` &#40;
    `id` int&#40;10&#41; unsigned NOT NULL auto_increment,
    `ip_addr` int&#40;10&#41; unsigned NOT NULL default '0',
    `uid` int&#40;10&#41; unsigned NOT NULL default '0',
    `use_start_date` int&#40;10&#41; unsigned NOT NULL default '0',
    `use_end_date` int&#40;10&#41; unsigned NOT NULL default '0',
    `last_calc_date` int&#40;10&#41; unsigned NOT NULL default '0',
  PRIMARY KEY  &#40;`id`&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251 PACK_KEYS=0;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;

sub create_remote_tariffs_current &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `tariffs_current` &#40;
    `id` int&#40;10&#41; unsigned NOT NULL auto_increment,
    `tid` int&#40;10&#41; unsigned NOT NULL default '0',
    `change_date` int&#40;10&#41; unsigned NOT NULL default '0',
    `change_uid` int&#40;10&#41; unsigned NOT NULL default '0',
    `name` text,
    `period_type` double NOT NULL default '0',
    `endperiod_zeroing_balance` int&#40;10&#41; unsigned NOT NULL default '0',
    `abon_pay_discount_period` float unsigned NOT NULL default '0',
    `abonpay` float NOT NULL default '0',
    `null_counters` int&#40;10&#41; unsigned NOT NULL default '0',
    `dont_discount_if_block` int&#40;10&#41; unsigned NOT NULL default '0',
    PRIMARY KEY  &#40;`id`&#41;
    &#41; ENGINE=MyISAM  DEFAULT CHARSET=cp1251 PACK_KEYS=0;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;

sub create_freeradius_tables &#123;

  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS frad_groupcheck &#40; 
    id int&#40;11&#41; unsigned NOT NULL auto_increment, 
    GroupName varchar&#40;64&#41; NOT NULL default '', 
    Attribute varchar&#40;32&#41; NOT NULL default '', 
    op char&#40;2&#41; NOT NULL DEFAULT '==', 
    Value varchar&#40;253&#41; NOT NULL default '', 
    PRIMARY KEY &#40;id&#41;, 
    KEY GroupName &#40;GroupName&#40;32&#41;&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251"&#41; or die $Mysql&#58;&#58;db_errstr;

  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS frad_groupreply &#40; 
    id int&#40;11&#41; unsigned NOT NULL auto_increment, 
    GroupName varchar&#40;64&#41; NOT NULL default '', 
    Attribute varchar&#40;32&#41; NOT NULL default '', 
    op char&#40;2&#41; NOT NULL DEFAULT '=', 
    Value varchar&#40;253&#41; NOT NULL default '', 
    prio int unsigned NOT NULL default '0', 
    PRIMARY KEY &#40;id&#41;, 
    KEY GroupName &#40;GroupName&#40;32&#41;&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251"&#41; or die $Mysql&#58;&#58;db_errstr;

  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS frad_usergroup &#40; 
    id int&#40;11&#41; unsigned NOT NULL auto_increment, 
    GroupName varchar&#40;64&#41; NOT NULL default '', 
    PRIMARY KEY &#40;id&#41;
  &#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251"&#41; or die $Mysql&#58;&#58;db_errstr;

  $dbremote->Query&#40;"REPLACE INTO frad_usergroup  VALUES &#40;1, 'users'&#41;"&#41; or die $Mysql&#58;&#58;db_errstr;
  $dbremote->Query&#40;"REPLACE INTO frad_groupcheck VALUES &#40;1, 'users', 'Simultaneous-Use', '&#58;=', '1'&#41;"&#41; or die $Mysql&#58;&#58;db_errstr;
  $dbremote->Query&#40;"REPLACE INTO frad_groupreply VALUES &#40;1, 'users', 'Framed-IP-Netmask', '&#58;=', '255.255.255.255', 0&#41;"&#41; or die $Mysql&#58;&#58;db_errstr;
  $dbremote->Query&#40;"REPLACE INTO frad_groupreply VALUES &#40;2, 'users', 'Exec-Program', '=', '/etc/raddb/begin -f %f -u %u -l %l', 0&#41;"&#41; or die $Mysql&#58;&#58;db_errstr;
  $dbremote->Query&#40;"REPLACE INTO frad_groupreply VALUES &#40;3, 'users', 'Acct-Interim-Interval', '=', '600', 0&#41;"&#41; or die $Mysql&#58;&#58;db_errstr;

&#125;

sub create_radius_packets_accounting &#123;
  $dbremote->Query&#40;"CREATE TABLE IF NOT EXISTS `radius_packets_accounting` &#40;
    `id` int&#40;10&#41; unsigned NOT NULL auto_increment,
    `uid` int&#40;10&#41; unsigned NOT NULL default '0',
    `recv_date` int&#40;10&#41; unsigned NOT NULL default '0',
    `Code` int&#40;10&#41; unsigned NOT NULL default '0',
    `Identifier` int&#40;10&#41; unsigned NOT NULL default '0',
    `Authentic` varchar&#40;255&#41; NOT NULL default '',
    `Framed_IP_Address` varchar&#40;255&#41; NOT NULL default '',
    `Acct_Authentic` varchar&#40;255&#41; NOT NULL default '',
    `NAS_Port` varchar&#40;255&#41; NOT NULL default '',
    `Acct_Delay_Time` int&#40;10&#41; unsigned NOT NULL default '0',
    `Service_Type` varchar&#40;255&#41; NOT NULL default '',
    `Acct_Session_Id` varchar&#40;255&#41; NOT NULL default '',
    `NAS_Port_Type` varchar&#40;255&#41; NOT NULL default '',
    `User_Name` varchar&#40;255&#41; NOT NULL default '',
    `Framed_Protocol` varchar&#40;255&#41; NOT NULL default '',
    `NAS_IP_Address` varchar&#40;255&#41; NOT NULL default '',
    `Acct_Status_Type` int&#40;10&#41; unsigned NOT NULL default '0',
    `Acct_Input_Packets` bigint&#40;20&#41; unsigned NOT NULL default '0',
    `Acct_Input_Octets` bigint&#40;20&#41; unsigned NOT NULL default '0',
    `Acct_Output_Packets` bigint&#40;20&#41; unsigned NOT NULL default '0',
    `Acct_Output_Octets` bigint&#40;20&#41; unsigned NOT NULL default '0',
    `Acct_Session_Time` bigint&#40;20&#41; unsigned NOT NULL default '0',
  PRIMARY KEY  &#40;`id`&#41;,
  KEY `uid` &#40;`recv_date`,`uid`,`Acct_Status_Type`,`Acct_Session_Id`&#41;,
  KEY `stop` &#40;`Acct_Session_Id`,`Identifier`&#41;
&#41; ENGINE=MyISAM DEFAULT CHARSET=cp1251;"&#41; or die $Mysql&#58;&#58;db_errstr;
&#125;
P.S. На самом деле он понадобился мне не только в качестве шутки и для разминки мозгов. Он пригодится для поддержания существующей инфраструктуры, развёрнутой в настоящий момент вокруг четвёрки (freeradius, dns, shaper) 8)

Закрыто