File Coverage

blib/lib/Config/Model/Backend/OpenSsh/Role/Reader.pm
Criterion Covered Total %
statement 62 69 89.8
branch 14 22 63.6
condition 5 9 55.5
subroutine 11 11 100.0
pod 0 3 0.0
total 92 114 80.7


line stmt bran cond sub pod time code
1             #
2             # This file is part of Config-Model-OpenSsh
3             #
4             # This software is Copyright (c) 2008-2022 by Dominique Dumont.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10 4     4   2396 use strict;
  4         10  
  4         146  
11 4     4   35 use warnings;
  4         10  
  4         255  
12              
13             package Config::Model::Backend::OpenSsh::Role::Reader ;
14             $Config::Model::Backend::OpenSsh::Role::Reader::VERSION = '2.9.4.1';
15 4     4   67 use 5.10.1;
  4         15  
16              
17 4     4   27 use Config::Model 2.128;
  4         88  
  4         195  
18              
19 4     4   26 use Mouse::Role ;
  4         8  
  4         44  
20             requires qw(read_global_comments associates_comments_with_data);
21              
22             # sub stub known as "forward" declaration
23             # required for Role consistency checks
24             # See Moose::Manual::Roles for details
25             sub current_node;
26              
27             has 'current_node' => (
28             is => 'rw',
29             isa => 'Config::Model::Node',
30             weak_ref => 1
31             ) ;
32              
33 4     4   1671 use Carp ;
  4         13  
  4         297  
34 4     4   36 use Log::Log4perl 1.11;
  4         94  
  4         32  
35              
36             my $logger = Log::Log4perl::get_logger("Backend::OpenSsh");
37              
38             my @dispatch = (
39             qr/match/i => 'match',
40             qr/host\b/i => 'host',
41             qr/(local|remote)forward/i => 'forward',
42             qr/^PreferredAuthentications$/ => 'comma_list',
43             qr/localcommand/i => 'assign',
44             qr/\w/ => 'assign',
45             );
46              
47             sub read {
48 26     26 0 2775578 my $self = shift ;
49 26         269 my %args = @_ ;
50             my $config_root = $args{object}
51 26   33     163 || croak __PACKAGE__," read_ssh_file: undefined config root object";
52              
53 26 100       116 return 0 unless $args{file_path}->is_file;
54              
55 23         714 $logger->info("loading config file ".$args{file_path});
56              
57 23         490 my @lines = $args{file_path}->lines_utf8 ;
58             # try to get global comments (comments before a blank line)
59 23         5605 $self->read_global_comments(\@lines,'#') ;
60              
61             # need to reset this when reading user ssh file after system ssh file
62 23         4201 $self->current_node($config_root) ;
63              
64 23         146 my @assoc = $self->associates_comments_with_data( \@lines, '#' ) ;
65 23         12590 foreach my $item (@assoc) {
66 315         916 my ( $vdata, $comment ) = @$item;
67              
68 315         2147 my ( $k, @v ) = split /\s+/, $vdata;
69              
70 315         665 my $i = 0;
71 315         919 while ( $i < @dispatch ) {
72 1618         3289 my ( $regexp, $sub ) = @dispatch[ $i++, $i++ ];
73 1618 100 66     8133 if ( $k =~ $regexp and $self->can($sub)) {
74 315         1450 $logger->trace("read_ssh_file: dispatch calls $sub");
75 315         3548 $self->$sub( $config_root, $k, \@v, $comment, $args{check} );
76 315         208310 last;
77             }
78              
79 1303 50       3445 warn __PACKAGE__, " unknown keyword: $k" if $i >= @dispatch;
80             }
81             }
82 23         415 return 1;
83             }
84              
85             sub comma_list {
86 3     3 0 16 my ($self,$root, $raw_key,$arg,$comment, $check) = @_ ;
87 3         24 $logger->debug("assign: $raw_key @$arg # $comment");
88              
89 3         33 my @list = map { split /\s*,\s*/ } @$arg;
  3         24  
90 3         13 $self->assign($root, $raw_key,\@list,$comment, $check);
91             }
92              
93             sub assign {
94 246     246 0 737 my ($self,$root, $raw_key,$arg,$comment, $check) = @_ ;
95 246         1493 $logger->debug("assign: $raw_key @$arg # $comment");
96              
97              
98             # keys are case insensitive, try to find a match
99 246         2604 my $key = $self->current_node->find_element ($raw_key, case => 'any') ;
100              
101 246 50       158536 if (not defined $key) {
102 0 0       0 if ($check eq 'yes') {
103             # drop if -force is not set
104 0         0 die "Error: unknown parameter: '$raw_key'. Use -force option to drop this parameter\n";
105             }
106             else {
107 0         0 say "Dropping parameter '$raw_key'" ;
108             }
109 0         0 return;
110             }
111              
112 246         942 my $elt = $self->current_node->fetch_element($key) ;
113 246         201893 my $type = $elt->get_type;
114             #print "got $key type $type and ",join('+',@$arg),"\n";
115              
116 246 100 66     1615 $elt->annotation($comment) if $comment and $type ne 'hash';
117              
118 246 100       3205 if ($type eq 'leaf') {
    100          
    50          
    0          
119 195         834 $elt->store( value => join(' ',@$arg), check => $check ) ;
120             }
121             elsif ($type eq 'list') {
122 48         181 $elt->push_x ( values => $arg, check => $check ) ;
123             }
124             elsif ($type eq 'hash') {
125 3         18 my $hv = $elt->fetch_with_id($arg->[0]);
126 3         1836 $hv->store( value => $arg->[1], check => $check );
127 3 50       1234 $hv->annotation($comment) if $comment;
128             }
129             elsif ($type eq 'check_list') {
130 0           my @check = split /\s*,\s*/,$arg->[0] ;
131 0           $elt->set_checked_list (\@check, check => 'skip') ;
132             }
133             else {
134 0           die "OpenSsh::assign did not expect $type for $key\n";
135             }
136             }
137              
138 4     4   4038 no Mouse;
  4         10  
  4         32  
139              
140             1;
141              
142             # ABSTRACT: Role to read OpenSsh config files
143              
144             __END__
145              
146             =pod
147              
148             =encoding UTF-8
149              
150             =head1 NAME
151              
152             Config::Model::Backend::OpenSsh::Role::Reader - Role to read OpenSsh config files
153              
154             =head1 VERSION
155              
156             version 2.9.4.1
157              
158             =head1 SYNOPSIS
159              
160             None. Consumed by L<Config::Model::Backend::OpenSsh::Ssh> and
161             L<Config::Model::Backend::OpenSsh::Sshd>.
162              
163             =head1 DESCRIPTION
164              
165             Read methods used by both L<Config::Model::Backend::OpenSsh::Ssh> and
166             L<Config::Model::Backend::OpenSsh::Sshd>.
167              
168             =head1 SEE ALSO
169              
170             L<cme>, L<Config::Model>, L<Config::Model::OpenSsh>
171              
172             =head1 AUTHOR
173              
174             Dominique Dumont
175              
176             =head1 COPYRIGHT AND LICENSE
177              
178             This software is Copyright (c) 2008-2022 by Dominique Dumont.
179              
180             This is free software, licensed under:
181              
182             The GNU Lesser General Public License, Version 2.1, February 1999
183              
184             =cut