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 )