Config-Model-Backend-Augeas

 view release on metacpan or  search on metacpan

lib/Config/Model/Backend/Augeas.pm  view on Meta::CPAN

        if ( not defined $args{$param} ) {
            Config::Model::Exception::Model->throw(
                error  => "read_augeas error: model " . "does not specify '$param' for Augeas ",
                object => $self->{node} );
        }
    }

    my $cdir = $self->get_tuned_config_dir(%args);
    $logger->info( "Read config data through Augeas in directory '$cdir' " . "file $args{file}" );

    my $mainpath = '/files' . $args{config_dir} . '/'. $args{file};

    my @result  = $self->augeas_deep_match($mainpath);
    my @cm_path = @result;

    # cleanup resulting path to remove Augeas '/files', remove the
    # file path and plug the remaining path where it is consistent in
    # the model. I.e if the file "root" matches a list element (like
    # for /etc/hosts), get this element name from "set_in" parameter
    my $set_in = $args{set_in} || '';
    foreach my $path (@cm_path) {
        $path =~ s!$mainpath!!;
        $path = "/$set_in/$path" if $set_in;
        $path  =~ s!/+!/!g;
    }

    # Create a hash of sequential lenses
    my %is_seq_lens = map { ( $_ => 1 ); } @{ $args{sequential_lens} || [] };

    my $augeas_obj = $self->{augeas_obj};

    # this may break as data will be written in the tree in an order
    # decided by Augeas. This may break complex model with warping as
    # the best writing order is indicated by the model stored in
    # Config::Model and not by Augeas.
    while (@result) {
        my $aug_p = shift @result;
        my $cm_p  = shift @cm_path;             # Config::Model path
        my $v     = $augeas_obj->get($aug_p);
        next unless defined $v;

        $logger->debug("read-augeas $aug_p, will set C::M path '$cm_p' with '$v'");

        $cm_p =~ s!^/!!;

        # With some list, we can get
        # /files/etc/ssh/sshd_config/AcceptEnv[1]/1/ =  LC_PAPER
        # /files/etc/ssh/sshd_config/AcceptEnv[1]/2/ =  LC_NAME
        # /files/etc/ssh/sshd_config/AcceptEnv[2]/3/ =  LC_ADDRESS
        # /files/etc/ssh/sshd_config/AcceptEnv[2]/4/ =  LC_TELEPHONE

        # Depending on the syntax, list can be in the form:
        # /files/etc/ssh/sshd_config/AcceptEnv[2]/3/   non-seq  ditch idx
        # /files/etc/hosts/4/                          non-seq
        # /files/etc/ssh/sshd_config/HostKey[2]         is-seq  keep idx

        # Likewise, hashes can be in the form
        # /files/etc/ssh/sshd_config/Subsystem[2]/foo/    is-seq ditch idx
        # /files/etc/ssh/sshd_config/Bar/foo/            non-seq

        my @cm_steps = split m!/+!, $cm_p;
        my $obj = $self->{node};
        $obj = $obj->fetch_element( shift @cm_steps ) if $set_in;

        while ( my $step = shift @cm_steps ) {
            my ( $label, $idx ) = ( $step =~ /(\w+)(?:\[(\d+)\])?/ );
            my $is_seq = $is_seq_lens{$label} || 0;
            $logger->debug( "read-augeas: step label $label "
                    . ( defined $idx ? "idx $idx " : '' )
                    . "(is_seq $is_seq)" );

            # idx will be treated next iteration if needed
            if (    $obj->get_type eq 'node'
                and $obj->element_type($label) eq 'list'
                and $is_seq ) {
                $idx = 1 unless defined $idx;
                $logger->debug("read-augeas: keep seq lens idx $idx");
                unshift @cm_steps, $idx;
            }

            if ( $label =~ /\[/ ) {
                Config::Model::Exception::Model->throw(
                    error => "read_augeas error: can't use $label with "
                        . "Augeas index in Config::Model. $label should "
                        . "probably be listed as 'sequential_lens'",
                    object => $self->{node} );
            }

            # augeas list begin at 1 not 0
            my $type = $obj->get_type ;
            $label -= 1 if $obj->get_type eq 'list';
            if ( scalar @cm_steps > 0 ) {
                $logger->debug("read-augeas: get $label");
                $obj = $obj->get($label);
            }
            elsif ($type eq 'check_list') {
                $logger->debug("read-augeas: set check_list $label $v");
                $obj->check( $v );
            }
            elsif ($type eq 'leaf') {
                $logger->debug("read-augeas: set leaf $label $v");
                $obj->store( $v );
            }
            else {
                # last step
                $logger->debug("read-augeas: set $type $label $v");
                $obj->set( $label , $v );
            }

            if ( not defined $obj ) {
                Config::Model::Exception::Model->throw(
                    error => "read_augeas error: '$cm_p' led to undef object. "
                        . "Check for errors in 'sequential_lens' specification",
                    object => $self->{node} );
            }
        }
    }

    return 1;
}



( run in 0.359 second using v1.01-cache-2.11-cpan-71847e10f99 )