File Coverage

blib/lib/Cfn/Dependencies.pm
Criterion Covered Total %
statement 18 54 33.3
branch 12 22 54.5
condition 3 6 50.0
subroutine 3 10 30.0
pod 0 9 0.0
total 36 101 35.6


line stmt bran cond sub pod time code
1             package Cfn::Dependencies {
2 22     22   14955 use Moose::Role;
  22         51  
  22         179  
3              
4             sub resolve_references_to_logicalid_with {
5 0     0 0 0 my ($self, $logical_id, $object) = @_;
6 0         0 $self->Properties->resolve_references_to_logicalid_with($logical_id, $object);
7             }
8              
9       0 0   sub resolve_parameters {
10             # Scan all resources resolving parameters to their value
11             }
12              
13       0 0   sub resolve_functions {
14             # Execute functions
15             }
16              
17       0 0   sub resolve_references {
18             #
19             }
20              
21             sub get_deps_from_object {
22 68     68 0 1131 my ($object, $deps) = @_;
23              
24 68 100       458 return $deps if (not defined $object);
25            
26 33 100 100     272 if ($object->isa('Cfn::Value::Array')) {
    100          
    100          
    50          
    100          
27 4         6 get_deps_from_object($_, $deps) for (@{ $object->Value });
  4         84  
28             } elsif ($object->isa('Cfn::Value::Function::Ref') or $object->isa('Cfn::Value::Function::GetAtt')) {
29 14         65 $deps->{ $object->LogicalId } = 1;
30             } elsif ($object->isa('Cfn::Value::Function')) {
31 1         25 get_deps_from_object($object->Value, $deps);
32             } elsif ($object->isa('Cfn::Value::Hash')) {
33 0         0 get_deps_from_object($object->Value->{ $_ }, $deps) for (keys %{ $object->Value });
  0         0  
34             } elsif ($object->isa('Cfn::Resource')) {
35             # Deps in attributes
36 12 50       201 if (defined $object->Properties) {
37 12         214 get_deps_from_object($object->Properties->$_, $deps) for map { $_->name } ($object->Properties->meta->get_all_attributes);
  48         1128  
38             }
39             # Add explicit DependsOn
40 12         37 $deps->{ $_ } = 1 for ($object->DependsOnList);
41             }
42 33         223 return $deps;
43             }
44              
45             sub dependencies {
46 12     12 0 19 my $self = shift;
47 12         19 return [ keys %{ get_deps_from_object($self, { }) } ];
  12         24  
48             }
49              
50             sub undeclared_dependencies {
51 0     0 0   my $self = shift;
52             # register all deps in
53 0   0       my @errors = grep { not $self->Resource($_) and not $self->Parameter($_) } @{ $self->dependencies };
  0            
  0            
54 0           return @errors;
55             }
56              
57             # Calculates the dependency tree between resources
58             # Dies upon circular dependencies or not declared resource
59             sub dependency_tree {
60 0     0 0   my($self, $deps, $dtree) = @_;
61 0           my @resources = $self->ResourceList;
62            
63 0 0         if (!$dtree) {
64 0           $dtree = Tree->new('root');
65 0           $deps = \@resources;
66             }
67            
68 0           foreach my $dep (@$deps) {
69 0           my $curr = Tree->new($dep);
70 0           $dtree->add_child($curr);
71            
72             # Detect circular dependencies
73 0 0         if ($dtree->depth > scalar @resources) {
74 0           my $dep_resources = {};
75 0           while (!$dtree->is_root) { # Approximate resources involved
76 0           $dep_resources->{$dtree->value} = 1; # in the circular dependency
77 0           $dtree = $dtree->parent;
78             }
79 0           die "Could not create dependency tree due to circular dependencies around resources: ". join(',', keys %$dep_resources)."\n";
80             }
81 0 0         die "Could not find resource $dep declared as a dependency of ".$dtree->value."\n" if(!$self->Resources->{$dep});
82 0           $curr = $self->dependency_tree( $self->Resources->{$dep}->DependsOn, $curr );
83             }
84 0           return $dtree;
85             }
86            
87             # Returns ArrayRef of resource names in order of creation to respect dependencies
88             sub resource_creation_order {
89 0     0 0   my $self = shift;
90 0           my $dep_tree = $self->dependency_tree;
91            
92 0           my @nodes = $dep_tree->traverse( $dep_tree->POST_ORDER );
93 0           pop @nodes; # ditch 'root' node
94            
95 0           my $created_resources = {};
96 0           my @create_order;
97             #my @create_order = map { $_->value } @nodes;
98            
99             # Avoid returning duplicates using aux hash?
100             # `·->Must! per distingir del cas de recursos amb noms duplicats
101 0           foreach (@nodes) {
102 0 0         push @create_order, $_->value unless($created_resources->{$_->value}); # if not created already
103 0           $created_resources->{$_->value} = 1;
104             }
105 0           return \@create_order;
106             }
107             }
108              
109             1;