File Coverage

blib/lib/Shell/Var/Reader/CMDB.pm
Criterion Covered Total %
statement 17 94 18.0
branch 0 50 0.0
condition 0 39 0.0
subroutine 6 7 85.7
pod 1 1 100.0
total 24 191 12.5


line stmt bran cond sub pod time code
1             package Shell::Var::Reader::CMDB;
2              
3 1     1   84087 use 5.006;
  1         4  
4 1     1   3 use strict;
  1         2  
  1         31  
5 1     1   3 use warnings;
  1         1  
  1         42  
6 1     1   447 use File::Slurp qw(read_dir write_file read_dir);
  1         32114  
  1         60  
7 1     1   401 use File::Copy;
  1         2503  
  1         52  
8 1     1   482 use String::ShellQuote;
  1         758  
  1         1102  
9              
10             =head1 NAME
11              
12             Shell::Var::Reader::CMDB - Helper for updating shell_var_reader based CMDBs.
13              
14             =head1 VERSION
15              
16             Version 0.5.0
17              
18             =cut
19              
20             our $VERSION = '0.5.0';
21              
22             =head1 SUBROUTINES
23              
24             =head2 update
25              
26             Reads through the directory and process all relevant files.
27              
28             Shell::Var::Reader::CMDB->update(
29             dir=>'./foo/',
30             verbose=>1,
31             );
32              
33             The following options are available.
34              
35             - dir :: Path to where to create it.
36             - Default :: undef.
37              
38             - verbose :: If it should be verbose or not.
39             - Default :: 1
40              
41             - to_process :: An optional array of groups or systems
42             to process by path.
43             - Default :: undef
44              
45             If dir undef, it will check the following
46             directories for the file '.shell_var_reader'.
47              
48             ./
49             ../
50             ../../
51             ../../../
52             ../../../../
53              
54             When using to_process, group and systems should not be mixed
55             as it will result in groups being ignored as systems is more
56             restrictive.
57              
58             Lets assume we have the following...
59              
60             ./group_a/foo.sh
61             ./group_a/bar.sh
62             ./group_b/nas.sh
63              
64             So if we have to_process set to ['group_a'] the following
65             would be processed...
66              
67             ./group_a/foo.sh
68             ./group_a/bar.sh
69              
70             So if we have to_process set to ['group_a/bar.sh'] the following
71             would be processed...
72              
73             ./group_a/bar.sh
74              
75             So if we have to_process set to ['group_a/bar.sh', 'group_b'] the following
76             would be processed...
77              
78             ./group_a/bar.sh
79              
80             =cut
81              
82             sub update {
83 0     0 1   my ( $empty, %opts ) = @_;
84              
85             # set the defaults
86 0           my $defaults = {
87             exists_okay => 1,
88             verbose => 1,
89             };
90 0           my @default_keys = keys( %{$defaults} );
  0            
91 0           foreach my $check_key (@default_keys) {
92 0 0         if ( !defined( $opts{$check_key} ) ) {
93 0           $opts{$check_key} = $defaults->{$check_key};
94             }
95             }
96              
97             # handle checking if the dir already exists and deciding what to do if it already does
98 0 0         if ( !defined( $opts{dir} ) ) {
99 0 0         if ( -f './.shell_var_reader' ) {
    0          
    0          
    0          
    0          
100 0           $opts{dir} = './';
101             } elsif ( -f '../.shell_var_reader' ) {
102 0           $opts{dir} = '../';
103             } elsif ( -f '../../.shell_var_reader' ) {
104 0           $opts{dir} = '../../';
105             } elsif ( -f '../../../.shell_var_reader' ) {
106 0           $opts{dir} = '../../../';
107             } elsif ( -f '../../../../.shell_var_reader' ) {
108 0           $opts{dir} = '../../../../';
109             }
110             } else {
111 0 0         if ( !-d $opts{dir} ) {
112 0           die( '"' . $opts{dir} . '" does not exist or is not a directory' );
113             }
114             }
115              
116 0           chdir( $opts{dir} );
117 0           $opts{dir} = './';
118              
119 0           my $has_specified_groups = 0;
120 0           my $has_specified_systems = 0;
121 0           my %specified_groups;
122             my %specified_systems;
123 0 0 0       if ( defined( $opts{to_process} )
      0        
      0        
      0        
124             && ref( $opts{to_process} ) eq 'ARRAY'
125             && defined( $opts{to_process}[0] )
126             && ( ref( $opts{to_process}[0] ) eq '' || ref( $opts{to_process}[0] ) eq 'SCALAR' ) )
127             {
128 0           foreach my $item ( @{ $opts{to_process} } ) {
  0            
129 0           $item =~ s/^\.\/+//;
130 0           $item =~ s/\/+$//;
131 0 0         if ( -d $item ) {
    0          
132 0           $specified_groups{$item} = 1;
133 0           $has_specified_groups = 1;
134             } elsif ( $item =~ /^[a-zA-Z0-9\.\_\-]+\/+[a-zA-Z0-9\.\_\-]+\.sh$/ ) {
135 0           my $group = $item;
136 0           $group =~ s/\/+.*$//;
137 0           $specified_groups{$group} = 1;
138              
139 0           my $system = $item;
140 0           $system =~ s/^.*\/+//;
141 0           $system =~ s/\.sh$//;
142 0           $specified_systems{$system} = 1;
143              
144 0           $has_specified_groups = 1;
145 0           $has_specified_systems = 1;
146             } ## end elsif ( $item =~ /^[a-zA-Z0-9\.\_\-]+\/+[a-zA-Z0-9\.\_\-]+\.sh$/)
147             } ## end foreach my $item ( @{ $opts{to_process} } )
148             } ## end if ( defined( $opts{to_process} ) && ref( ...))
149              
150             # make sure this file exists, ortherwise likely not a directory this should be operating on
151 0 0         if ( !-f $opts{dir} . '/.shell_var_reader' ) {
152             die( 'Does not appear to be a directory for cmdb_shell_var_reader ... "'
153             . $opts{dir}
154 0           . '/.shell_var_reader" does not exist or is not a file' );
155             }
156              
157             # figure out if it should use the munger or not
158 0           my $munger_option = '';
159 0 0         if ( -f $opts{dir} . '/munger.pl' ) {
160 0           $munger_option = '-m ../munger.pl';
161             }
162              
163             #
164 0           my $no_toml='';
165 0 0         if ( -f $opts{dir} . '/.no_toml' ) {
166 0           $no_toml = '--no_toml';
167             }
168              
169             # get a list of directories to process and start work on it
170 0           chdir( $opts{dir} );
171             my @system_groups = grep {
172 0 0 0       -d $_
      0        
      0        
      0        
      0        
      0        
173             && !-f "$_/.not_a_system_group"
174             && $_ !~ /^\./
175             && $_ ne 'json_confs'
176             && $_ ne 'shell_confs'
177             && $_ ne 'toml_confs'
178             && $_ ne 'yaml_confs'
179             && $_ ne 'cmdb'
180 0           } read_dir( $opts{dir} );
181 0           foreach my $sys_group ( sort(@system_groups) ) {
182 0           my $process_group = 1;
183 0 0 0       if ( $has_specified_groups && !$specified_groups{$sys_group} ) {
184 0           $process_group = 0;
185             }
186              
187 0 0         if ($process_group) {
188 0 0         if ( $opts{verbose} ) {
189 0           print "Processing group $sys_group ... \n";
190             }
191              
192             my @systems_in_group
193 0 0 0       = grep { -f $sys_group . '/' . $_ && $_ =~ /\.sh$/ && $_ !~ /^\_/ } read_dir($sys_group);
  0            
194 0           chdir($sys_group);
195 0           foreach my $system ( sort(@systems_in_group) ) {
196 0           my $cmdb_host = $system;
197 0           $cmdb_host =~ s/\.sh$//;
198              
199 0           my $process_system = 1;
200 0 0 0       if ( $has_specified_systems && !$specified_systems{$cmdb_host} ) {
201 0           $process_system = 0;
202             }
203              
204 0 0         if ($process_system) {
205 0 0         if ( $opts{verbose} ) {
206 0           print $cmdb_host. "\n";
207             }
208 0           my $command
209             = 'shell_var_reader -r '
210             . shell_quote($system)
211             . ' --tcmdb ../cmdb/ -s -p --cmdb_host '
212             . shell_quote($cmdb_host) . ' '
213             . $no_toml . ' '
214             . $munger_option
215             . ' -o multi -d ../';
216 0           print `$command`;
217              
218             } else {
219 0 0         if ( $opts{verbose} ) {
220 0           print 'skipping ' . $cmdb_host . "\n";
221             }
222             }
223             } ## end foreach my $system ( sort(@systems_in_group) )
224 0 0         if ( $opts{verbose} ) {
225 0           print "\n\n";
226             }
227 0           chdir('..');
228             } else {
229 0 0         if ( $opts{verbose} ) {
230 0           print "Skipping group $sys_group ... \n\n\n";
231             }
232             }
233             } ## end foreach my $sys_group ( sort(@system_groups) )
234             } ## end sub update
235              
236             =head1 LAYOUT & WORKFLOW
237              
238             Specifically named files.
239              
240             - .shell_var_reader :: Marks the base directory as being for a shell_var_reader CMDB.
241              
242             Specifically named directories.
243              
244             - cmdb :: The TOML CMDB directory.
245             - json_confs :: Generated JSON confs.
246             - shell_confs :: Generated shell confs.
247             - toml_confs :: Generated TOML confs.
248             - yaml_confs :: Generated YAML confs.
249              
250             Other directories that that don't start with a '.' or contiain a file named '.not_a_system_group'
251             will be processed as system groups.
252              
253             TOML will be skipped if .no_toml exists in the base directory.
254              
255             These directories will be searched for files directly below them for files ending in '.sh' and not
256             starting with either a '_' or a '.'. The name used for a system is the name of the file minus the ending
257             '.sh', so 'foo.bar.sh' would generate a config for a system named 'foo.bar'.
258              
259             When it finds a file to use as a system config, it will point shell_var_reader at it with TOML CMDB enabled
260             and with the name of that system set the hostname to use with the TOML CMDB. That name will also be saved as
261             the variable 'SYSTEM_NAME', provided that variable is not defined already. If a 'munger.pl' exists, that file
262             is used as the munger file. shell_var_reader will be ran four times, once to generate each config type.
263              
264             =head1 AUTHOR
265              
266             Zane C. Bowers-Hadley, C<< <vvelox at vvelox.net> >>
267              
268             =head1 BUGS
269              
270             Please report any bugs or feature requests to C<bug-shell-var-reader at rt.cpan.org>, or through
271             the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Shell-Var-Reader>. I will be notified, and then you'll
272             automatically be notified of progress on your bug as I make changes.
273              
274             =head1 SUPPORT
275              
276             You can find documentation for this module with the perldoc command.
277              
278             perldoc Shell::Var::Reader
279              
280              
281             You can also look for information at:
282              
283             =over 4
284              
285             =item * RT: CPAN's request tracker (report bugs here)
286              
287             L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Shell-Var-Reader>
288              
289             =item * Search CPAN
290              
291             L<https://metacpan.org/release/Shell-Var-Reader>
292              
293             =back
294              
295              
296             =head1 ACKNOWLEDGEMENTS
297              
298              
299             =head1 LICENSE AND COPYRIGHT
300              
301             This software is Copyright (c) 2023 by Zane C. Bowers-Hadley.
302              
303             This is free software, licensed under:
304              
305             The Artistic License 2.0 (GPL Compatible)
306              
307              
308             =cut
309              
310             1; # End of Shell::Var::Reader