File Coverage

blib/lib/Net/Amazon/R53/ResourceRecordSet/Stub.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             #
2             # This file is part of Net-Amazon-R53
3             #
4             # This software is Copyright (c) 2012 by Campus Explorer, Inc.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10             package Net::Amazon::R53::ResourceRecordSet::Stub;
11             {
12             $Net::Amazon::R53::ResourceRecordSet::Stub::VERSION = '0.002'; # TRIAL
13             }
14              
15             # ABSTRACT: A representation of a ResourceRecordSet
16              
17 3     3   238463 use utf8;
  3         30  
  3         16  
18              
19 3     3   1378 use Moose;
  0            
  0            
20             use MooseX::MarkAsMethods autoclean => 1;
21             use MooseX::StrictConstructor;
22             use Moose::Util::TypeConstraints qw{ enum class_type };
23             use MooseX::AlwaysCoerce;
24             use MooseX::AttributeShortcuts 0.017;
25             use MooseX::Params::Validate;
26             use MooseX::Types::Moose ':all';
27             use MooseX::Types::Common::Numeric ':all';
28             use MooseX::Types::Common::String ':all';
29              
30             use aliased 'MooseX::CoercePerAttribute';
31              
32             use Data::Compare;
33              
34             use overload
35             '==' => sub { shift->is_equivalent_to(shift) },
36             '!=' => sub { ! shift->is_equivalent_to(shift) },
37             fallback => 1,
38             ;
39              
40             with 'MooseX::Traitor';
41              
42             # "anon" type constraint
43             use constant RecordType => enum [ qw{ A AAAA CNAME MX NS PTR SOA SPF SRV TXT } ];
44              
45             # debugging...
46             #use Smart::Comments '###';
47              
48              
49             has name => (
50             traits => [ CoercePerAttribute ],
51             is => 'ro',
52             isa => NonEmptySimpleStr,
53             required => 1,
54             constraint => sub { /\.$/ },
55             coerce => {
56             NonEmptySimpleStr() => sub { "$_." },
57             },
58             );
59              
60             has type => (is => 'ro', isa => RecordType, required => 1);
61             has ttl => (is => 'ro', isa => PositiveOrZeroInt, predicate => 1);
62              
63             has resource_records => (is => 'ro', isa => 'ArrayRef[Str]', builder => sub { [ ] });
64              
65             # alias sets only
66             has alias_target => (
67             traits => ['Hash'],
68             is => 'ro',
69             isa => HashRef[NonEmptySimpleStr],
70             predicate => 1,
71             handles => {
72             alias_target_hosted_zone_id => [ get => 'HostedZoneId' ],
73             alias_target_dns_name => [ get => 'DNSName' ],
74             },
75             );
76              
77             # weighted + latency
78             has set_identifier => (is => 'ro', isa => 'Str', predicate => 1);
79              
80             # weighted only
81             has weight => (
82             is => 'ro',
83             isa => PositiveOrZeroInt,
84             constraint => sub { $_ < 256 },
85             predicate => 1,
86             );
87              
88             # latency only
89             has region => (is => 'ro', isa => 'Str', predicate => 1);
90              
91              
92             sub new_from_net_dns_rr {
93             my $class = shift @_;
94             #my ($rr, $origin, $opts) = validated_list \@_,
95             my ($rr, $opts) = validated_list \@_,
96             rr => { isa => class_type('Net::DNS::RR') },
97             #origin => { isa => NonEmptySimpleStr, default => '.' },
98             opts => { isa => 'HashRef', default => { } },
99             ;
100              
101             # this is made significantly easier in that if we're using a Net::DNS::RR
102             # to create a stub, there will be no Route53-specific functionality
103             # involved; so we'll always have a ttl (even if just 0), no alias or
104             # weighted records, etc...
105              
106             confess 'Cannot convert a Net::DNS::RR with class: ' . $rr->class
107             unless $rr->class eq 'IN';
108              
109             # fixup our origin; must start/stop with a .
110             #$origin .= '.' unless $origin =~ /\.$/;
111             #$origin = ".$origin" unless $origin =~ /^\./;
112              
113             # fixup our name; append $origin unless already fully-qualified
114             my $name = $rr->name;
115             # ## name and origin: "$name / $origin"
116             #$name .= $origin unless $name =~ /\.$/;
117             $name .= '.' unless $name =~ /\.$/;
118              
119             my %params = (
120             type => $rr->type,
121             name => $name,
122             ttl => $rr->ttl || 0,
123              
124             resource_records => [
125             $rr->rdatastr,
126             ],
127             );
128              
129             ### %params
130             ### $opts
131              
132             %params = (%params, %$opts);
133             return $class->new(%params);
134             }
135              
136              
137             sub is_equivalent_to {
138             my ($self, $other) = @_;
139              
140             confess 'cannot compare with ' . ref $other
141             unless $other->isa('Net::Amazon::R53::ResourceRecordSet::Stub');
142              
143             my $_eq = sub { my $name = shift; $self->$name() eq $other->$name() };
144             my $_peq = sub {
145             my $name = shift;
146             my $pred = "has_$name";
147              
148             my $self_has = $self->$pred() ? 1 : 0;
149             my $other_has = $other->$pred() ? 1 : 0;
150              
151             return 1 if $self_has + $other_has == 0;
152             return if $self_has + $other_has == 1;
153              
154             return $self->$name().q{} eq $other->$name().q{};
155             };
156              
157             # we could really do this in a nicer fashion by looking at the metaclasses
158             # and using attribute tags to store how we should use them to compare.
159              
160             do { return unless $_eq->($_) }
161             for qw{ name type };
162              
163             do{ return unless $_peq->($_) }
164             for qw{ set_identifier weight region ttl };
165              
166             return unless Compare($self->alias_target, $other->alias_target);
167             };
168              
169             __PACKAGE__->meta->make_immutable;
170             !!42;
171              
172             __END__
173              
174             =pod
175              
176             =encoding utf-8
177              
178             =for :stopwords Chris Weyl Campus Explorer, Inc ttl
179              
180             =head1 NAME
181              
182             Net::Amazon::R53::ResourceRecordSet::Stub - A representation of a ResourceRecordSet
183              
184             =head1 VERSION
185              
186             This document describes version 0.002 of Net::Amazon::R53::ResourceRecordSet::Stub - released January 09, 2013 as part of Net-Amazon-R53.
187              
188             =head1 DESCRIPTION
189              
190             This class represents a R53 resource record set, "in the raw", as it were; a
191             record without an owning zone. Stubs are useful both when specifing what a
192             R53 entry should look like, as well as for operations that just need the info,
193             and don't care if it's actually in an R53 hosted zone.
194              
195             =head1 OVERVIEW
196              
197             See the Amazon R53 API doc for legal values and uses, at the moment.
198              
199             Note that we do basic validation here, and allow R53 itself to tell us when
200             values are off.
201              
202             =head1 REQUIRED ATTRIBUTES
203              
204             These attributes are required, and must have their values supplied during object construction.
205              
206             =head2 name
207              
208             Per the Route53 documentation, this is expected to always be a fully-qualified
209             domain name. As such, we attempt to coerce by adding a '.' to the end of the
210             supplied name if not present. This behaviour may change.
211              
212             =head2 type
213              
214             One of the R53 supported types:
215              
216             A AAAA CNAME MX NS PTR SOA SPF SRV TXT
217              
218             =head1 ATTRIBUTES
219              
220             =head2 ttl
221              
222             =head2 resource_records
223              
224             =head2 alias_target
225              
226             =head2 set_identifier
227              
228             =head2 weight
229              
230             =head2 region
231              
232             =head1 METHODS
233              
234             =head2 new_from_net_dns_rr($rr, { %opts })
235              
236             Takes a L<Net::DNS::RR> and creates a stub record instance off its type.
237              
238             The C<%opts> optional argument is a hashref of additional options to pass to
239             our stub constructor; they will override anything we set.
240              
241             Note that we _cannot_ take any Route53 specific record options here, as
242             L<Net::DNS> doesn't know anything about them. Also, the L<Net::DNS::RR> being
243             passed in must be fully qualified; we don't have any good way to handle origin
244             right now, and simply append a '.' to C<$rr->name>.
245              
246             =head2 is_equivalent_to($stub)
247              
248             Given another stub, we check the records for equality.
249              
250             =head1 SEE ALSO
251              
252             Please see those modules/websites for more information related to this module.
253              
254             =over 4
255              
256             =item *
257              
258             L<Net::Amazon::R53|Net::Amazon::R53>
259              
260             =back
261              
262             =head1 AUTHOR
263              
264             Chris Weyl <cweyl@campusexplorer.com>
265              
266             =head1 CONTRIBUTOR
267              
268             Chris Weyl <cweyl@alumni.drew.edu>
269              
270             =head1 COPYRIGHT AND LICENSE
271              
272             This software is Copyright (c) 2012 by Campus Explorer, Inc.
273              
274             This is free software, licensed under:
275              
276             The GNU Lesser General Public License, Version 2.1, February 1999
277              
278             =cut