zoukankan      html  css  js  c++  java
  • keepalive配置文件转化JSON

    无论在管理LVS配置中,对keepalive的配置文件管理是必不可少的,解析配置文件也是核心功能之一,现在把自己写的一些思路分享给大家~

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
    use JSON;
    use re 'eval';
    #将keepalived.conf 格式化为json数据
     
     
    my $file = "/Users/machenlong/Downloads/keepalived.conf";
    open FH, $file or die "$!";
    #一次行读取整个文件
    my $str = do { local $/; <FH> };
    #定义树形中的键值对
    my $treeKey = {
        vrrpKey => {
            state             => 1,
            interface         => 1,
            virtual_router_id => 1,
            priority          => 1,
            advert_int        => 1,
        },
        virtualKey => {
            delay_loop => 1,
            lb_algo    => 1,
            lb_kind    => 1,
            protocol   => 1
        },
        realKey => {
            realKey0 => { weight => 1, },
            realKey1 => {
     
                TCP_CHECK => 1,
                HTTP_GET  => 1
     
            },
            realKey2 => {
                connect_timeout    => 1,
                nb_get_retry       => 1,
                delay_before_retry => 1,
                connect_port       => 1,
     
            },
            realKey3 => {
                url         => 1,
                path        => 1,
                status_code => 1
            }
        }
    };
    my $hash;
    my $re
        = qr/(.*)s+{(?{local $a=0})(?>(?:([^{}]+)(?{push @{$hash->{$1}},$2;})| 
    #将匹配到得内容push到$hash
    #固化分组,减少回朔。
    {(?{$a++})|   
    #遇到开括号$a+1
    }(?(?{$a!=0})(?{$a--})|       
    #如果$a不等于0则遇到闭括号$a-1
    (?!)))*)(?(?{$a!=0})(?!))}/x;
     
    # 否则继续匹配,如果继续遇到$a不等于0 继续匹配到行尾
     
    #处理注释
    $str =~ s/
    #.*$//mg;
     
    1 while ( $str =~ /$re/g );
    my ( $formatHash, $vrrpFormat );
    for my $key ( keys %$hash ) {
        for ( @{ $hash->{$key} } ) {
            vrrp_format( $key, $_, $treeKey );
        }
    }
     
    my $confFormat = real_format( $vrrpFormat, $treeKey );
     
    print encode_json $confFormat;
     
    sub vrrp_format {
        my ( $varrKey, $varrParam, $treeKey ) = @_;
        my ( $realIp, $realPort, $key3, @unParams );
        if ( $varrKey =~ /(global_defs)/ ) {
            my @params = split ' ', $varrParam;
            $vrrpFormat->{$1}->{ $params[0] } = $params[1];
        }
     
        
    #vvrp 分解
        elsif ( $varrKey =~ /(vrrp.*?)s+(w+)/ ) {
            my ( $key, $value ) = ( $1, $2 );
            my @params = split ' ', $varrParam;
            my $ips;
            for ( 0 .. $
    #params ) {
                my @v = splice @params, 0, 2;
                if (@v) {
                    if ( $treeKey->{vrrpKey}->{ $v[0] } ) {
                        $vrrpFormat->{$key}->{$value}->{ $v[0] } = $v[1];
                    }
                    else {
     
                        for (@v) {
     
                            
    #IP处理
                            if (/(d+.){3}d+/) {
                                push @{ $vrrpFormat->{$key}->{$value}
                                        ->{virtual_ipaddress} }, $_;
                            }
     
                            
    #auth字段处理
                            elsif (/auth_/) {
                                $vrrpFormat->{$key}->{$value}->{authentication}
                                    ->{ $v[0] } = $v[1];
                            }
     
                        }
                    }
     
                }
            }
     
        }
     
        
    #virtual_server处理
        elsif ( $varrKey =~ /(virtual_server)s+((?:d+.){3}d+)s+(d+)/ ) {
     
            
    #键值名,IP,端口
            my ( $key, $ip, $port ) = ( $1, $2, $3 );
            my @params = split ' ', $varrParam;
            for ( 0 .. $
    #params ) {
     
                
    #切分数组前两个元素
                my @v = splice @params, 0, 2;
                if (@v) {
                    if ( $treeKey->{virtualKey}->{ $v[0] } ) {
                        $vrrpFormat->{$key}->{$ip}->{$port}->{ $v[0] } = $v[1];
                    }
                    else {
                        
    #不匹配定义的检测,重新写回@params
                        unshift @params, @v;
                    }
                }
            }
     
            if (@params) {
     
                
    #将剩余的params写回总hash,real_serverArr临时数组
                push @{ $vrrpFormat->{$key}->{$ip}->{$port}->{real_serverArr} },
                    @params;
            }
        }
     
    }
     
    sub real_format {
        my ( $vrrpFormat, $treeKey ) = @_;
     
        for my $sIp ( keys %{ $vrrpFormat->{virtual_server} } ) {
            my $portHash = $vrrpFormat->{virtual_server}->{$sIp};
            for my $port ( keys %$portHash ) {
     
                my @realArr = @{ $portHash->{$port}->{real_serverArr} };
     
                
    #realserver  IP、port  位置
                my ($realIp, $realPort, @pos);
                 
     
                
    #3级 4级 键值类型,数值
                my ( $key3, $key4, $value4, $key5 );
     
                
    #查找IP的POS未知
                for ( 0 .. $
    #realArr ) {
                    if ( $realArr[$_] =~ /(?:d+.){3}d+/ ) {
                        push @pos, $_;
     
                    }
                }
                my ( @realIp, @realPort );
                my $cPos = 0;
     
                
    #根据位置,将IP端口放入数组
                for (@pos) {
                    push @realIp,   splice @realArr, $_ - $cPos, 1;
                    push @realPort, splice @realArr, $_ - $cPos, 1;
                    $cPos += 2;
                }
     
                for my $realParam ( @realArr) {
     
                    
    #根据real_server未知确定IP、端口未知
                    if ( $realParam eq "real_server" ) {
                        $realIp   = shift @realIp;
                        $realPort = shift @realPort;
                        next;
                    }
                    
    #遇到TCP_CHECK HTTP_GET url作为分支,存入key3
                    if ( $realParam =~ /(TCP_CHECK)/ ) {
                        $key3 = $1;
     
                    }
                    elsif ( $realParam =~ /(HTTP_GET)/ ) {
                        $key3 = $1;
                    }
                    elsif ( $realParam =~ /(url)/ ) {
                        $key5 = $1;
     
                    }
                    if ( !$key4 and $realParam !~ /HTTP_GET|TCP_CHECK/ ) {
                        $key4 = $realParam;
                    }
                    
    #匹配为键值对逻辑
                    if ( $key4 and !$value4 ) {
                        
    #必须为数字
                        if ( $realParam =~ /^d+$/ ) {
                            $value4 = $realParam;
                        }
                        
    #或者为url
                        elsif ( $realParam =~ /https?:/// ) {
                            $value4 = $realParam;
                        }
                    }
     
                    if ( $key4 and $value4 and $key3 ) {
     
                        
    # print "$realIp,$key3,$key4,$value4n";
                        
    #判断键值对是否在定义中存在
                        if ( $treeKey->{realKey}->{realKey0}->{$key4} ) {
     
                            $portHash->{$port}->{real_server}->{$realIp}
                                ->{$realPort}->{$key4} = $value4;
     
                        }
                        elsif ( $treeKey->{realKey}->{realKey2}->{$key4} ) {
                            $portHash->{$port}->{real_server}->{$realIp}
                                ->{$realPort}->{$key3}->{$key4} = $value4;
                        }
                        
    #url判断
                        elsif ($key5) {
                            $portHash->{$port}->{real_server}->{$realIp}
                                ->{$realPort}->{$key3}->{$key5}->{$key4}
                                = $value4;
                        }
                        undef $key4;
                        undef $value4;
                    }
                    
    #删除临时存储数组
                    delete $portHash->{$port}->{real_serverArr};
                }
            }
        }
        return $vrrpFormat;
    }
  • 相关阅读:
    Ceph的参数mon_osd_down_out_subtree_limit细解
    java:警告:[unchecked] 对作为普通类型 java.util.HashMap 的成员的put(K,V) 的调用未经检查
    Java 原始类型JComboBox的成员JComboBox(E())的调用 未经过检查
    Android draw Rect 坐标图示
    不用快捷键就能使用Eclipse的自动完成功能
    Java 窗体居中 通用代码
    Java文件复制删除操作合集
    Java Toolkit类用法
    DEVEXPRESS 破解方法
    如何使用Java执行cmd命令
  • 原文地址:https://www.cnblogs.com/mcshell/p/5655795.html
Copyright © 2011-2022 走看看