File Coverage

blib/lib/Net/Amazon/Route53/HostedZone.pm
Criterion Covered Total %
statement 24 53 45.2
branch 0 10 0.0
condition n/a
subroutine 8 10 80.0
pod 2 2 100.0
total 34 75 45.3


line stmt bran cond sub pod time code
1 2     2   13 use strict;
  2         5  
  2         72  
2 2     2   10 use warnings;
  2         3  
  2         82  
3              
4             package Net::Amazon::Route53::HostedZone;
5             $Net::Amazon::Route53::HostedZone::VERSION = '0.173450';
6 2     2   8 use Moo;
  2         5  
  2         15  
7 2     2   572 use Types::Standard qw(InstanceOf Str ArrayRef);
  2         4  
  2         10  
8 2     2   1132 use HTML::Entities;
  2         5  
  2         128  
9              
10 2     2   814 use Net::Amazon::Route53::Change;
  2         6  
  2         53  
11 2     2   755 use Net::Amazon::Route53::ResourceRecordSet;
  2         5  
  2         1450  
12              
13             =head2 SYNOPSIS
14              
15             my $hostedzone = Net::Amazon::Route53::HostedZone->new(...);
16             # use methods on $hostedzone
17              
18             =cut
19              
20             =head2 ATTRIBUTES
21              
22             =cut
23              
24             =head3 route53
25              
26             A L object, needed and used to perform requests
27             to Amazon's Route 53 service
28              
29             =cut
30              
31             has 'route53' => ( is => 'rw', isa => InstanceOf['Net::Amazon::Route53'], required => 1, weak_ref => 1 );
32              
33             =head3 id
34              
35             The hosted zone's id
36              
37             =head3 name
38              
39             The hosted zone's name; ends in a dot, i.e.
40              
41             example.com.
42              
43             =head3 callerreference
44              
45             The CallerReference attribute for the hosted zone
46              
47             =head3 comment
48              
49             Any Comment given when the zone is created
50              
51             =cut
52              
53             has 'id' => ( is => 'rw', isa => Str, required => 1, default => '' );
54             has 'name' => ( is => 'rw', isa => Str, required => 1, default => '' );
55             has 'callerreference' => ( is => 'rw', isa => Str, required => 1, default => '' );
56             has 'comment' => ( is => 'rw', isa => Str, required => 1, default => '' );
57              
58             =head3 nameservers
59              
60             Lazily loaded, returns a list of the nameservers authoritative for this zone
61              
62             =cut
63              
64             has 'nameservers' => (
65             is => 'rw',
66             isa => ArrayRef[Str],
67             lazy => 1,
68             default => sub {
69             my $self = shift;
70             my $resp = $self->route53->request( 'get', 'https://route53.amazonaws.com/2010-10-01/' . $self->id );
71             my @nameservers = map { decode_entities($_) } @{ $resp->{DelegationSet}{NameServers}{NameServer} };
72             \@nameservers;
73             }
74             );
75              
76             =head3 resource_record_sets
77              
78             Lazily loaded, returns a list of the resource record sets
79             (L objects) for this zone.
80              
81             =cut
82              
83             has 'resource_record_sets' => (
84             is => 'rw',
85             isa => ArrayRef,
86             lazy => 1,
87             default => sub {
88             my $self = shift;
89             my $next_record_name = '';
90             my @resource_record_sets;
91             while (1) {
92             my $resp = $self->route53->request('get',
93             'https://route53.amazonaws.com/2010-10-01/'
94             . $self->id
95             . '/rrset?maxitems=100'
96             . $next_record_name);
97             my $set = $resp->{ResourceRecordSets}{ResourceRecordSet};
98             my @results = ref($set) eq 'ARRAY' ? @$set : ($set);
99             for my $res ( @results ) {
100             push @resource_record_sets,
101             Net::Amazon::Route53::ResourceRecordSet->new(
102             route53 => $self->route53,
103             hostedzone => $self,
104             name => decode_entities($res->{Name}),
105             ttl => $res->{TTL} || 0,
106             type => decode_entities($res->{Type}),
107             values => [
108             map { decode_entities($_->{Value}) } @{
109             ref $res->{ResourceRecords}{ResourceRecord} eq 'ARRAY'
110             ? $res->{ResourceRecords}{ResourceRecord}
111             : [ $res->{ResourceRecords}{ResourceRecord} ]
112             }
113             ],
114             );
115             }
116             last unless $resp->{NextRecordName};
117             $next_record_name = '&name='.$resp->{NextRecordName};
118             }
119             \@resource_record_sets;
120             }
121             );
122              
123             =head2 METHODS
124              
125             =cut
126              
127             =head3 create
128              
129             Creates a new zone. Needs all the attributes (name, callerreference and comment).
130              
131             Takes an optional boolean parameter, C, to indicate whether the request should
132             return straightaway (default, or when C is C<0>) or it should wait until the
133             request is C according to the Change's status.
134              
135             Returns a L object representing the change requested.
136              
137             =cut
138              
139             sub create
140             {
141 0     0 1   my $self = shift;
142 0           my $wait = shift;
143 0 0         $wait = 0 if !defined $wait;
144 0 0         $self->name =~ /\.$/ or die "Zone name needs to end in a dot, to be created\n";
145 0           my $request_xml_str = <<'ENDXML';
146            
147            
148             %s
149             %s
150            
151             %s
152            
153            
154             ENDXML
155 0           my $request_xml = sprintf( $request_xml_str, map { $_ } $self->name, $self->callerreference, $self->comment );
  0            
156 0           my $resp = $self->route53->request(
157             'post',
158             'https://route53.amazonaws.com/2010-10-01/hostedzone',
159             'content-type' => 'text/xml; charset=UTF-8',
160             Content => $request_xml,
161             );
162 0           $self->id( $resp->{HostedZone}{Id} );
163             my $change = Net::Amazon::Route53::Change->new(
164             route53 => $self->route53,
165 0           ( map { lc($_) => decode_entities($resp->{ChangeInfo}{$_}) } qw/Id Status SubmittedAt/ ),
  0            
166             );
167 0           $change->refresh();
168 0 0         return $change if !$wait;
169              
170 0           while ( lc( $change->status ) ne 'insync' ) {
171 0           sleep 2;
172 0           $change->refresh();
173             }
174 0           return $change;
175             }
176              
177             =head3 delete
178              
179             Deletes the zone. A zone can only be deleted by Amazon's Route 53 service if it
180             contains no records other than a SOA or NS.
181              
182             Takes an optional boolean parameter, C, to indicate whether the request should
183             return straightaway (default, or when C is C<0>) or it should wait until the
184             request is C according to the Change's status.
185              
186             Returns a L object representing the change requested.
187              
188             =cut
189              
190             sub delete
191             {
192 0     0 1   my $self = shift;
193 0           my $wait = shift;
194 0 0         $wait = 0 if !defined $wait;
195 0           my $resp = $self->route53->request( 'delete', 'https://route53.amazonaws.com/2010-10-01/' . $self->id, );
196             my $change = Net::Amazon::Route53::Change->new(
197             route53 => $self->route53,
198 0           ( map { lc($_) => decode_entities($resp->{ChangeInfo}{$_}) } qw/Id Status SubmittedAt/ ),
  0            
199             );
200 0           $change->refresh();
201 0 0         return $change if !$wait;
202 0           while ( lc( $change->status ) ne 'insync' ) {
203 0           sleep 2;
204 0           $change->refresh();
205             }
206 0           return $change;
207             }
208              
209 2     2   13 no Moo;
  2         29  
  2         8  
210              
211             =head1 AUTHOR
212              
213             Marco FONTANI
214              
215             =head1 COPYRIGHT AND LICENSE
216              
217             This software is copyright (c) 2011 by Marco FONTANI.
218              
219             This is free software; you can redistribute it and/or modify it under
220             the same terms as the Perl 5 programming language system itself.
221              
222             =cut
223              
224             1;