File Coverage

blib/lib/Clustericious/Config/Helpers.pm
Criterion Covered Total %
statement 61 90 67.7
branch 7 16 43.7
condition n/a
subroutine 19 26 73.0
pod 12 12 100.0
total 99 144 68.7


line stmt bran cond sub pod time code
1             package Clustericious::Config::Helpers;
2              
3 51     51   201509 use strict;
  51         133  
  51         1438  
4 51     51   272 use warnings;
  51         218  
  51         2919  
5 51     51   897 use 5.010001;
  51         167  
6 51     51   8599 use Hash::Merge qw/merge/;
  51         113285  
  51         3004  
7 51     51   786 use Data::Dumper;
  51         5418  
  51         2621  
8 51     51   300 use Carp qw( croak );
  51         103  
  51         1936  
9 51     51   268 use base qw( Exporter );
  51         99  
  51         4575  
10 51     51   7734 use JSON::MaybeXS qw( encode_json );
  51         115749  
  51         2898  
11 51     51   844 use Clustericious::Config;
  51         120  
  51         38772  
12              
13             # ABSTRACT: Helpers for clustericious config files.
14             our $VERSION = '1.27'; # VERSION
15              
16              
17             our @mergeStack;
18             our @EXPORT = qw( extends_config get_password home file dir hostname hostname_full json yaml address public_address interface );
19              
20              
21             sub extends_config
22             {
23 3     3 1 10 my($name, @args) = @_;
24 3         29 push @mergeStack, Clustericious::Config->new($name, \@args);
25 3         12 return '';
26             }
27              
28             #
29             #
30             # do_merges:
31             #
32             # Called after reading all config files, to process extends_config
33             # directives.
34             #
35             sub _do_merges {
36 104     104   284 my($class, $data) = @_;
37              
38 104 100       376 return $data unless @mergeStack;
39              
40             # Nested extends_config's form a tree which we traverse depth first.
41 3         16 Hash::Merge::set_behavior( 'RIGHT_PRECEDENT' );
42 3         67 my %so_far = %{ shift @mergeStack };
  3         21  
43 3         17 while (my $c = shift @mergeStack)
44             {
45 0         0 my %h = %$c;
46 0         0 %so_far = %{ merge( \%so_far, \%h ) };
  0         0  
47             }
48 3         7 %$data = %{ merge( \%so_far, $data ) };
  3         12  
49             }
50              
51              
52             sub get_password
53             {
54 3     3 1 15 return Clustericious::Config::Callback::Password->new->to_yaml;
55             }
56              
57              
58             sub home (;$)
59             {
60 4     4 1 16 require File::Glob;
61 4 100       144 $_[0] ? File::Glob::bsd_glob("~$_[0]") : File::Glob::bsd_glob('~');
62             }
63              
64              
65             sub file
66             {
67 1     1 1 2 eval { require Path::Class::File };
  1         5  
68 1 50       6 croak "file helper requires Path::Class" if $@;
69 1         6 Path::Class::File->new(@_);
70             }
71              
72              
73             sub dir
74             {
75 1     1 1 4 require Path::Class::Dir;
76 1 50       4 croak "dir helper requires Path::Class" if $@;
77 1         6 Path::Class::Dir->new(@_);
78             }
79              
80              
81             sub hostname
82             {
83 1     1 1 1 state $hostname;
84            
85 1 50       4 unless(defined $hostname)
86             {
87 1         5 require Sys::Hostname;
88 1         3 $hostname = Sys::Hostname::hostname();
89 1         9 $hostname =~ s/\..*$//;
90             }
91            
92 1         3 $hostname;
93             }
94              
95              
96             sub hostname_full
97             {
98 1     1 1 4 require Sys::Hostname;
99 1         3 Sys::Hostname::hostname();
100             }
101              
102              
103             sub json ($)
104             {
105 1     1 1 7 encode_json($_[0]);
106             }
107              
108              
109             sub yaml ($)
110             {
111 1     1 1 6 require YAML::XS;
112 1         2 local $YAML::UseHeader = 0;
113 1         51 my $str = YAML::XS::Dump($_[0]);
114 1         8 $str =~ s{^---\n}{};
115 1         3 $str;
116             }
117              
118              
119             # TODO: for now the filtering of loop back only works on Linux
120             # and any system where the loopback interface is lo
121              
122             sub address (;$)
123             {
124 0     0 1   my($if) = @_;
125            
126 0           require Sys::HostAddr;
127            
128 0     0     my $filter = sub { !/^lo$/ };
  0            
129            
130 0 0         if(defined $if)
131             {
132 0 0         if(ref $if eq 'Regexp')
    0          
133             {
134 0     0     $filter = sub { $_ =~ $if };
  0            
135             }
136             elsif(ref $if eq 'ARRAY')
137             {
138 0           my %if = map { $_ => 1 } @$if;
  0            
139 0     0     $filter = sub { $if{$_} }
140 0           }
141             else
142             {
143 0     0     $filter = sub { $_ eq $if };
  0            
144             }
145             }
146              
147 0           my @if = grep { $filter->() } @{ Sys::HostAddr->new(ipv=>4)->interfaces };
  0            
  0            
148 0           map { @{ $_->addresses } } map { Sys::HostAddr->new(ipv => 4, interface => $_) } @if;
  0            
  0            
  0            
149             }
150              
151              
152             sub public_address ()
153             {
154 0     0 1   require Sys::HostAddr;
155 0           Sys::HostAddr->new(ipv=>4)->public;
156             }
157              
158              
159             sub interface ()
160             {
161 0     0 1   require Sys::HostAddr;
162 0           grep !/^lo$/, @{ Sys::HostAddr->new(ipv=>4)->interfaces };
  0            
163             }
164              
165              
166             1;
167              
168             __END__
169              
170             =pod
171              
172             =encoding UTF-8
173              
174             =head1 NAME
175              
176             Clustericious::Config::Helpers - Helpers for clustericious config files.
177              
178             =head1 VERSION
179              
180             version 1.27
181              
182             =head1 SYNOPSIS
183              
184             ---
185             % extend_config 'SomeOtherConfig';
186              
187             =head1 DESCRIPTION
188              
189             This module provides the functions available in all configuration files
190             using L<Clustericious::Config>.
191              
192             =head1 FUNCTIONS
193              
194             =head2 extends_config
195              
196             % extends_config $config_name, %arguments
197              
198             Extend the config using another config file.
199              
200             =head2 get_password
201              
202             <%= get_password %>
203              
204             Prompt for a password. This will prompt the user the first time it is
205             encountered for a password.
206              
207             =head2 home
208              
209             <%= home %>
210             <%= home $user %>
211              
212             Return the given users' home directory, or if no user is
213             specified return the calling user's home directory.
214              
215             =head2 file
216              
217             <%= file @list %>
218              
219             The C<file> shortcut from Path::Class, if it is installed.
220              
221             =head2 dir
222              
223             <%= dir @list %>
224              
225             The C<dir> shortcut from Path::Class, if it is installed.
226              
227             =head2 hostname
228              
229             <%= hostname %>
230              
231             The system hostname (uses L<Sys::Hostname>)
232              
233             =head2 hostname_full
234              
235             <%= hostname_full %>
236              
237             The system hostname in full, including the domain, if
238             it can be determined (uses L<Sys::Hostname>).
239              
240             =head2 json
241              
242             <%= json $ref %>
243              
244             Encode the given hash or list reference.
245              
246             =head2 yaml
247              
248             <%= yaml $ref %>
249              
250             Encode the given hash or list reference.
251              
252             =head2 address
253              
254             <%= address %>
255             <%= address $interface %>
256              
257             Returns a list of IP addresses. Requires L<Sys::HostAddr> to be installed.
258             C<$interfaces>, if specified may be either a string or regular expression.
259             For example you can do C<address qr{^en[0-9]+$}> on Linux to get only ethernet
260             interfaces.
261              
262             By default does not return loop back interfaces.
263              
264             Only returns IPv4 addresses.
265              
266             =head2 public_address
267              
268             <%= public_address %>
269              
270             Returns the public IPv4 address. May not be an address on your host, if you
271             are behind a firewall. Requires L<Sys::HostAddr> to be installed.
272              
273             =head2 interface
274              
275             <%= join ' ', interfaces %>
276              
277             Returns a list of network interfaces. Requires L<Sys::HostAddr> to be installed.
278              
279             By default does not return loop back interfaces.
280              
281             =head1 SEE ALSO
282              
283             L<Clustericious::Config>, L<Clustericious>
284              
285             =head1 AUTHOR
286              
287             Original author: Brian Duggan
288              
289             Current maintainer: Graham Ollis E<lt>plicease@cpan.orgE<gt>
290              
291             Contributors:
292              
293             Curt Tilmes
294              
295             Yanick Champoux
296              
297             =head1 COPYRIGHT AND LICENSE
298              
299             This software is copyright (c) 2013 by NASA GSFC.
300              
301             This is free software; you can redistribute it and/or modify it under
302             the same terms as the Perl 5 programming language system itself.
303              
304             =cut