Net-DNS-CloudFlare-DDNS-v0.63.1000755001751001751 012676225675 15350 5ustar00peterpeter000000000000README100644001751001751 52112676225675 16267 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1 This archive contains the distribution Net-DNS-CloudFlare-DDNS, version v0.63.1: Object Orientated Dynamic DNS Interface to CloudFlare DNS This software is Copyright (c) 2016 by Peter Roberts. This is free software, licensed under: The MIT (X11) License This README file was generated by Dist::Zilla::Plugin::Readme v5.043. Changes100644001751001751 213312676225675 16723 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1Revision history for Net-DNS-CloudFlare-DDNS v0.63.1 2016-03-28 - Test with TravisCI - use new interface of CloudFlare::Client - update dist.ini - Move to github - switch to V-string - Fix previous version changelog - Changes to work with Pod::Weave / Test::Synopsis properly 0.06_3 2014-10-02 - Fix more bugs - Bits and bobs - Update repo info - git repo split 0.06_2 2014-08-26 - Fix bugs 0.06_1 2014-08-19 - Moo -> Moose - add no indirect 'fatal' - Zone IDs are updated per each batch of updates so online changes to DNS don't cause problems - Failures are handled per DNS record update - Rewrite to be resilient and fault tolerant. Failures of any expected type handled without dying - Rewrite to use CloudFlare::Client - Use IP lookup services in a random order - Use Dist::Zilla to build 0.06 2013-03-06 - Lower depenency versions 0.05 2013-11-13 - Fix docs - Prettify code 0.04 2013-11-06 - Sort out POD properly 0.03 2013-11-06 - Split into Net::DNS::CloudFlare::DDNS 0.02 2013-10-30 - Added -v switch 0.01 2013-10-30 - Part of DDFlare INSTALL100644001751001751 201612676225675 16461 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1This is the Perl distribution Net-DNS-CloudFlare-DDNS. Installing Net-DNS-CloudFlare-DDNS is straightforward. ## Installation with cpanm If you have cpanm, you only need one line: % cpanm Net::DNS::CloudFlare::DDNS If you are installing into a system-wide directory, you may need to pass the "-S" flag to cpanm, which uses sudo to install the module: % cpanm -S Net::DNS::CloudFlare::DDNS ## Installing with the CPAN shell Alternatively, if your CPAN shell is set up, you should just be able to do: % cpan Net::DNS::CloudFlare::DDNS ## Manual installation As a last resort, you can manually install it. Download the tarball, untar it, then build it: % perl Makefile.PL % make && make test Then install it: % make install If you are installing into a system-wide directory, you may need to run: % sudo make install ## Documentation Net-DNS-CloudFlare-DDNS documentation is available as POD. You can run perldoc from a shell to read the documentation: % perldoc Net::DNS::CloudFlare::DDNS LICENSE100644001751001751 221012676225675 16431 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1This software is Copyright (c) 2016 by Peter Roberts. This is free software, licensed under: The MIT (X11) License The MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. MANIFEST100644001751001751 125212676225675 16562 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.043. Changes INSTALL LICENSE MANIFEST META.json META.yml Makefile.PL README cpanfile lib/Net/DNS/CloudFlare/DDNS.pm lib/Net/DNS/CloudFlare/DDNS/Types.pm t/00-compile.t t/01-main.t t/author-clean-namespaces.t t/author-critic.t t/author-eol.t t/author-mojibake.t t/author-no-tabs.t t/author-pod-coverage.t t/author-pod-syntax.t t/author-test-version.t t/release-cpan-changes.t t/release-dist-manifest.t t/release-distmeta.t t/release-fixme.t t/release-kwalitee.t t/release-meta-json.t t/release-minimum-version.t t/release-pod-linkcheck.t t/release-portability.t t/release-synopsis.t t/release-unused-vars.t META.yml100644001751001751 265012676225675 16705 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1--- abstract: 'Object Orientated Dynamic DNS Interface to CloudFlare DNS' author: - 'Peter Roberts ' build_requires: File::Spec: '0' IO::Handle: '0' IPC::Open3: '0' IPC::System::Simple: '0' Test::CPAN::Meta::JSON: '0' Test::Exception: '0' Test::More: '0' Try::Tiny: '0' blib: '1.01' perl: '5.008' strict: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 5.043, CPAN::Meta::Converter version 2.150005' license: mit meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Net-DNS-CloudFlare-DDNS provides: Net::DNS::CloudFlare::DDNS: file: lib/Net/DNS/CloudFlare/DDNS.pm version: v0.63.1 Net::DNS::CloudFlare::DDNS::Types: file: lib/Net/DNS/CloudFlare/DDNS/Types.pm version: v0.63.1 requires: Carp: '0' CloudFlare::Client: '0' List::Util: '0' Modern::Perl: '0' Moose: '0' MooseX::StrictConstructor: '0' Readonly: '0' TryCatch: '0' Type::Library: '0' Type::Utils: 0.039_12 Types::Standard: '0' autodie: '0' indirect: '0' namespace::autoclean: '0' perl: '5.008' warnings: '0' resources: bugtracker: https://github.com/pwr22/Net-DNS-CloudFlare-DDNS/issues homepage: https://metacpan.org/pod/Net::DNS::CloudFlare::DDNS repository: git://github.com/pwr22/Net-DNS-CloudFlare-DDNS.git version: v0.63.1 x_contributors: - 'Peter Roberts ' cpanfile100644001751001751 305312676225675 17136 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1requires "Carp" => "0"; requires "CloudFlare::Client" => "0"; requires "List::Util" => "0"; requires "Modern::Perl" => "0"; requires "Moose" => "0"; requires "MooseX::StrictConstructor" => "0"; requires "Readonly" => "0"; requires "TryCatch" => "0"; requires "Type::Library" => "0"; requires "Type::Utils" => "0.039_12"; requires "Types::Standard" => "0"; requires "autodie" => "0"; requires "indirect" => "0"; requires "namespace::autoclean" => "0"; requires "perl" => "5.008"; requires "warnings" => "0"; on 'test' => sub { requires "File::Spec" => "0"; requires "IO::Handle" => "0"; requires "IPC::Open3" => "0"; requires "IPC::System::Simple" => "0"; requires "Test::CPAN::Meta::JSON" => "0"; requires "Test::Exception" => "0"; requires "Test::More" => "0"; requires "Try::Tiny" => "0"; requires "blib" => "1.01"; requires "perl" => "5.008"; requires "strict" => "0"; }; on 'configure' => sub { requires "ExtUtils::MakeMaker" => "0"; }; on 'develop' => sub { requires "Pod::Coverage::TrustPod" => "0"; requires "Test::CPAN::Changes" => "0.19"; requires "Test::CPAN::Meta" => "0"; requires "Test::CPAN::Meta::JSON" => "0.16"; requires "Test::CleanNamespaces" => "0.15"; requires "Test::EOL" => "0"; requires "Test::Kwalitee" => "1.21"; requires "Test::Mojibake" => "0"; requires "Test::More" => "0.88"; requires "Test::NoTabs" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Pod::LinkCheck" => "0"; requires "Test::Synopsis" => "0"; requires "Test::Version" => "1"; }; META.json100644001751001751 601112676225675 17050 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1{ "abstract" : "Object Orientated Dynamic DNS Interface to CloudFlare DNS", "author" : [ "Peter Roberts " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 5.043, CPAN::Meta::Converter version 2.150005", "license" : [ "mit" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Net-DNS-CloudFlare-DDNS", "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "develop" : { "requires" : { "Pod::Coverage::TrustPod" : "0", "Test::CPAN::Changes" : "0.19", "Test::CPAN::Meta" : "0", "Test::CPAN::Meta::JSON" : "0.16", "Test::CleanNamespaces" : "0.15", "Test::EOL" : "0", "Test::Kwalitee" : "1.21", "Test::Mojibake" : "0", "Test::More" : "0.88", "Test::NoTabs" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08", "Test::Pod::LinkCheck" : "0", "Test::Synopsis" : "0", "Test::Version" : "1" } }, "runtime" : { "requires" : { "Carp" : "0", "CloudFlare::Client" : "0", "List::Util" : "0", "Modern::Perl" : "0", "Moose" : "0", "MooseX::StrictConstructor" : "0", "Readonly" : "0", "TryCatch" : "0", "Type::Library" : "0", "Type::Utils" : "0.039_12", "Types::Standard" : "0", "autodie" : "0", "indirect" : "0", "namespace::autoclean" : "0", "perl" : "5.008", "warnings" : "0" } }, "test" : { "requires" : { "File::Spec" : "0", "IO::Handle" : "0", "IPC::Open3" : "0", "IPC::System::Simple" : "0", "Test::CPAN::Meta::JSON" : "0", "Test::Exception" : "0", "Test::More" : "0", "Try::Tiny" : "0", "blib" : "1.01", "perl" : "5.008", "strict" : "0" } } }, "provides" : { "Net::DNS::CloudFlare::DDNS" : { "file" : "lib/Net/DNS/CloudFlare/DDNS.pm", "version" : "v0.63.1" }, "Net::DNS::CloudFlare::DDNS::Types" : { "file" : "lib/Net/DNS/CloudFlare/DDNS/Types.pm", "version" : "v0.63.1" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/pwr22/Net-DNS-CloudFlare-DDNS/issues" }, "homepage" : "https://metacpan.org/pod/Net::DNS::CloudFlare::DDNS", "repository" : { "type" : "git", "url" : "git://github.com/pwr22/Net-DNS-CloudFlare-DDNS.git", "web" : "https://github.com/pwr22/Net-DNS-CloudFlare-DDNS" } }, "version" : "v0.63.1", "x_contributors" : [ "Peter Roberts " ] } t000755001751001751 012676225675 15534 5ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.101-main.t100644001751001751 167012676225675 17227 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl -T # Aims to test basic usage of Net::DNS::CloudFlare::DDNS use Modern::Perl '2012'; use autodie ':all'; no indirect 'fatal'; use Readonly; use Test::More; use Test::Exception; use Try::Tiny; use Net::DNS::CloudFlare::DDNS; plan tests => 2; Readonly my $USER => 'blah'; Readonly my $KEY => 'blah'; Readonly my $ZONES => [{ zone => 'zone1', domains => [ 'dom1', 'dom2' ],}, { zone => 'zone2', domains => [ 'dom3', 'dom4'],},]; # Construction Readonly my $CLASS => 'Net::DNS::CloudFlare::DDNS'; lives_ok { $CLASS->new( user => $USER, apikey => $KEY, zones => $ZONES)} "construction with valid credentials works"; Readonly my $ddns => try { Net::DNS::CloudFlare::DDNS::->new( user => $USER, apikey => $KEY, zones => $ZONES,)}; # This should fail in any number of ways but continue despite emitting warnings lives_ok { $ddns->update; }; Makefile.PL100644001751001751 423212676225675 17404 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.043. use strict; use warnings; use 5.008; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "Object Orientated Dynamic DNS Interface to CloudFlare DNS", "AUTHOR" => "Peter Roberts ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "Net-DNS-CloudFlare-DDNS", "LICENSE" => "mit", "MIN_PERL_VERSION" => "5.008", "NAME" => "Net::DNS::CloudFlare::DDNS", "PREREQ_PM" => { "Carp" => 0, "CloudFlare::Client" => 0, "List::Util" => 0, "Modern::Perl" => 0, "Moose" => 0, "MooseX::StrictConstructor" => 0, "Readonly" => 0, "TryCatch" => 0, "Type::Library" => 0, "Type::Utils" => "0.039_12", "Types::Standard" => 0, "autodie" => 0, "indirect" => 0, "namespace::autoclean" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "File::Spec" => 0, "IO::Handle" => 0, "IPC::Open3" => 0, "IPC::System::Simple" => 0, "Test::CPAN::Meta::JSON" => 0, "Test::Exception" => 0, "Test::More" => 0, "Try::Tiny" => 0, "blib" => "1.01", "strict" => 0 }, "VERSION" => "v0.63.1", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Carp" => 0, "CloudFlare::Client" => 0, "File::Spec" => 0, "IO::Handle" => 0, "IPC::Open3" => 0, "IPC::System::Simple" => 0, "List::Util" => 0, "Modern::Perl" => 0, "Moose" => 0, "MooseX::StrictConstructor" => 0, "Readonly" => 0, "Test::CPAN::Meta::JSON" => 0, "Test::Exception" => 0, "Test::More" => 0, "Try::Tiny" => 0, "TryCatch" => 0, "Type::Library" => 0, "Type::Utils" => "0.039_12", "Types::Standard" => 0, "autodie" => 0, "blib" => "1.01", "indirect" => 0, "namespace::autoclean" => 0, "strict" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); 00-compile.t100644001751001751 241412676225675 17727 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/tuse 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.054 use Test::More; plan tests => 2 + ($ENV{AUTHOR_TESTING} ? 1 : 0); my @module_files = ( 'Net/DNS/CloudFlare/DDNS.pm', 'Net/DNS/CloudFlare/DDNS/Types.pm' ); # no fake home requested my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib'; use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L my $stderr = IO::Handle->new; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { require blib; blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING}; author-eol.t100644001751001751 76512676225675 20130 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::EOL 0.18 use Test::More 0.88; use Test::EOL; my @files = ( 'lib/Net/DNS/CloudFlare/DDNS.pm', 'lib/Net/DNS/CloudFlare/DDNS/Types.pm', 't/00-compile.t', 't/01-main.t' ); eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; done_testing; author-critic.t100644001751001751 66612676225675 20626 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; use Test::More; use English qw(-no_match_vars); eval "use Test::Perl::Critic"; plan skip_all => 'Test::Perl::Critic required to criticise code' if $@; Test::Perl::Critic->import( -profile => "perlcritic.rc" ) if -e "perlcritic.rc"; all_critic_ok(); release-fixme.t100644001751001751 43412676225675 20570 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } # This test is generated by Dist::Zilla::Plugin::Test::Fixme use strict; use warnings; use Test::Fixme; run_tests(); author-no-tabs.t100644001751001751 73312676225675 20707 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15 use Test::More 0.88; use Test::NoTabs; my @files = ( 'lib/Net/DNS/CloudFlare/DDNS.pm', 'lib/Net/DNS/CloudFlare/DDNS/Types.pm', 't/00-compile.t', 't/01-main.t' ); notabs_ok($_) foreach @files; done_testing; author-mojibake.t100644001751001751 40212676225675 21116 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings qw(all); use Test::More; use Test::Mojibake; all_files_encoding_ok(); release-synopsis.t100644001751001751 31612676225675 21346 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use Test::Synopsis; all_synopsis_ok(); release-distmeta.t100644001751001751 43012676225675 21266 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } # This file was automatically generated by Dist::Zilla::Plugin::MetaTests. use Test::CPAN::Meta; meta_yaml_ok(); release-kwalitee.t100644001751001751 53312676225675 21265 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } # this test was generated with Dist::Zilla::Plugin::Test::Kwalitee 2.12 use strict; use warnings; use Test::More 0.88; use Test::Kwalitee 1.21 'kwalitee_ok'; kwalitee_ok(); done_testing; author-pod-syntax.t100644001751001751 50312676225675 21445 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); release-meta-json.t100644001751001751 32212676225675 21351 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use Test::CPAN::Meta::JSON; meta_json_ok(); author-pod-coverage.t100644001751001751 56512676225675 21722 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } # This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests. use Test::Pod::Coverage 1.08; use Pod::Coverage::TrustPod; all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); author-test-version.t100644001751001751 107112676225675 22022 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::Version 1.05 use Test::Version; my @imports = qw( version_all_ok ); my $params = { is_strict => 0, has_version => 1, multiple => 0, }; push @imports, $params if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); Test::Version->import(@imports); version_all_ok; done_testing; release-portability.t100644001751001751 53512676225675 22024 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::More; eval 'use Test::Portability::Files'; plan skip_all => 'Test::Portability::Files required for testing portability' if $@; run_tests(); release-unused-vars.t100644001751001751 62012676225675 21731 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use Test::More 0.96 tests => 1; eval { require Test::Vars }; SKIP: { skip 1 => 'Test::Vars required for testing for unused vars' if $@; Test::Vars->import; subtest 'unused vars' => sub { all_vars_ok(); }; }; release-cpan-changes.t100644001751001751 52112676225675 22004 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::More 0.96 tests => 2; use_ok('Test::CPAN::Changes'); subtest 'changes_ok' => sub { changes_file_ok('Changes'); }; done_testing(); release-pod-linkcheck.t100644001751001751 77512676225675 22203 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use strict; use warnings; use Test::More; foreach my $env_skip ( qw( SKIP_POD_LINKCHECK ) ){ plan skip_all => "\$ENV{$env_skip} is set, skipping" if $ENV{$env_skip}; } eval "use Test::Pod::LinkCheck"; if ( $@ ) { plan skip_all => 'Test::Pod::LinkCheck required for testing POD'; } else { Test::Pod::LinkCheck->new->all_pod_ok; } release-dist-manifest.t100644001751001751 46612676225675 22234 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use Test::More; eval "use Test::DistManifest"; plan skip_all => "Test::DistManifest required for testing the manifest" if $@; manifest_ok(); release-minimum-version.t100644001751001751 52612676225675 22620 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t#!perl BEGIN { unless ($ENV{RELEASE_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for release candidate testing'); } } use Test::More; eval "use Test::MinimumVersion"; plan skip_all => "Test::MinimumVersion required for testing minimum versions" if $@; all_minimum_version_from_metayml_ok(); author-clean-namespaces.t100644001751001751 61212676225675 22537 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/t BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::CleanNamespaces 0.006 use Test::More 0.94; use Test::CleanNamespaces 0.15; subtest all_namespaces_clean => sub { all_namespaces_clean() }; done_testing; CloudFlare000755001751001751 012676225675 21231 5ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/lib/Net/DNSDDNS.pm100644001751001751 2505012676225675 22501 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/lib/Net/DNS/CloudFlarepackage Net::DNS::CloudFlare::DDNS; # ABSTRACT: Object Orientated Dynamic DNS Interface to CloudFlare DNS use Modern::Perl '2012'; use autodie ':all'; no indirect 'fatal'; use namespace::autoclean; use Moose; use MooseX::StrictConstructor; use Types::Standard qw( Bool Str); use Net::DNS::CloudFlare::DDNS::Types qw( CloudFlareClient LWPUserAgent); use TryCatch; use Carp; use Readonly; use List::Util 'shuffle'; # first dotted decimal version and args as hash interface use CloudFlare::Client 'v0.55.1'; our $VERSION = 'v0.63.1'; # VERSION has 'verbose' => ( is => 'rw', isa => Bool); # CF credentials has '_user' => ( is => 'ro', isa => Str, required => 1, init_arg => 'user'); has '_key' => ( is => 'ro', isa => Str, required => 1, init_arg => 'apikey'); # Configuration of zones, and their domains, to update has '_config' => ( is => 'ro', required => 1, init_arg => 'zones'); # Provides CF access sub _buildApi { CloudFlare::Client::->new( user => $_[0]->_user, apikey => $_[0]->_key)} has '_api' => ( is => 'ro', isa => CloudFlareClient, builder => '_buildApi', lazy => 1, init_arg => undef); # Fetch zone IDs for a single zone # The api call can fail and this will die # Returns a map of domain => id sub _getDomainIds { Readonly my $self => shift; Readonly my $zone => shift; # Query CloudFlare say "Trying domain IDs lookup for $zone" if $self->verbose; Readonly my $info => $self->_api->rec_load_all( z => $zone); # Filter to just A records and get a list of [domain => id] my @pairs = map { $_->{type} eq 'A' ? [ $_->{name} => $_->{rec_id} ] : () } @{ $info->{recs}{objs}}; # Localise hostnames to within zone, set zone itself to undef map { $_->[0] eq $zone ? $_->[0] = undef : $_->[0] =~ s/\.$zone$//} @pairs; # Build into a hash of domain => id my $map; foreach (@pairs) { my ($domain, $id) = @$_; carp "Duplicate domain $domain found in $zone - ", 'this is probably a mistake' if exists $map->{$domain}; $map->{$domain} = $id} return $map } # Build a mapping of zones to domain ID mappings from CF # Zones will be missing if their fetch fails but the show must go on sub _buildDomIds { Readonly my $self => shift; # $zone is a hash of config info my $map; for my $zone (@{ $self->_config }) { Readonly my $name => $zone->{zone}; Readonly my $domains => $zone->{domains}; # Try to fetch domain ids for this zone my $zoneMap; try { $zoneMap = $self->_getDomainIds($name)} catch (CloudFlare::Client::Exception::Upstream $e) { carp "Fetching zone IDs for $name failed because the " , 'CloudFlare API threw an error: ', $e->errorCode, ' ', $e->message} catch (CloudFlare::Client::Exception::Connection $e) { carp "Fetching zone IDs for $name failed because the " , 'connection to the CloudFlare API failed: ', $e->status, ' ', $e->message} # Install ids into map under $map->{\$_} = $zoneMap->{$_} foreach @$domains} return $map } # For storing domain IDs # A map of domain ref => IP has '_domIds' => ( is => 'ro', init_arg => undef, # Clear this and use lazy rebuilding to update IDs each run clearer => '_clearDomIds', builder => '_buildDomIds', lazy => 1); # For keeping track of what we last set the IPs to # A hash of domain ref -> IP sub _buildLastIps { {} } has _lastIps => ( is => 'rw', init_arg => undef, builder => '_buildLastIps'); # Used for fetching the IP Readonly my $UA_STRING => __PACKAGE__ . "/$VERSION"; sub _buildUa { Readonly my $ua => LWP::UserAgent::->new; $ua->agent($UA_STRING); return $ua} has _ua => ( is => 'ro', isa => LWPUserAgent, builder => '_buildUa', init_arg => undef); # Get an IP from any of a number of web services # each of which return just an IP Readonly my @IP_URLS => map { "http://$_" } ( 'icanhazip.com', 'ifconfig.me/ip', 'curlmyip.com'); sub _getIp { Readonly my $self => shift; say 'Trying to get current IP' if $self->verbose; # Try each service till we get an IP # Randomised order for balancing for my $serviceUrl (shuffle @IP_URLS) { say "Trying IP lookup at $serviceUrl" if $self->verbose; # Get and return IP Readonly my $res => $self->_ua->get($serviceUrl); if($res->is_success) { # Chop off the newline chomp(my $ip = $res->decoded_content); say "IP lookup at $serviceUrl returned $ip" if $self->verbose; return $ip } # Else log this lookup as failing and try another service carp "IP lookup at $serviceUrl failed: ", $res->status_line; } # All lookups have failed carp 'Could not lookup IP'; return } Readonly my $REC_TYPE => 'A'; Readonly my $TTL => '1'; sub update { Readonly my $self => shift; # Try to get the current IP address carp "Cannot update records without an IP" and return unless Readonly my $ip => $self->_getIp; # Try to update each zone for my $zone (@{ $self->_config }) { # Try to update each domain say "Trying to update records for $zone->{zone}" if $self->verbose; for my $dom (@{ $zone->{domains} }) { # Skip update unless there is a change in IP do { no warnings 'uninitialized'; if ($self->_lastIps->{\$dom} eq $ip) { say "IP not changed for $dom, skipping update" if $self->verbose; next}}; # Cannot update if domain ID couldn't be found # At this point new domain IDs will be pulled in from CF warn "Domain ID not found for $dom, cannot update" and next unless defined $self->_domIds->{\$dom}; # Update IP say "Trying to update IP for $dom" if $self->verbose; try { $self->_api->rec_edit( z => $zone->{zone}, type => $REC_TYPE, id => $self->_domIds->{\$dom}, name => $dom, content => $ip, ttl => $TTL,); # Record the new IP - won't happen if we fail above $self->_lastIps->{\$dom} = $ip} catch (CloudFlare::Client::Exception::Upstream $e) { carp "Updating IP for $dom in $zone->{zone} failed ", 'because the CloudFlare API threw an error: ', $e->errorCode, ' ', $e->message} catch (CloudFlare::Client::Exception::Connection $e) { carp "Updating IP for $dom in $zone->{zone} failed ", 'because the connection to the CloudFlare API failed: ', $e->status, ' ', $e->message}}} # Flush domain IDs so they're updated next run $self->_clearDomIds } 1; # End of Net::DNS::CloudFlare::DDNS __END__ =pod =encoding UTF-8 =head1 NAME Net::DNS::CloudFlare::DDNS - Object Orientated Dynamic DNS Interface to CloudFlare DNS =head1 VERSION version v0.63.1 =for test_synopsis my ($CF_USER, $CF_KEY, $ZONE_CONF); =head1 SYNOPSIS Provides an object orientated dynamic DNS interface for CloudFlare use Net::DNS::CloudFlare::DDNS; my $ddns = Net::DNS::CloudFlare::DDNS->new( user => $CF_USER, apikey => $CF_KEY, zones => $ZONE_CONF ); $ddns->update(); ... =head1 ATTRIBUTES =head2 verbose Whether or not the object should be verbose # Verbosity on $ddns->verbose(1); # Verbosity off $ddns->verbose(0); # Print current verbosity say $ddns->verbose; =head1 METHODS =head2 new Create a new Dynamic DNS object my $ddns = Net::DNS::CloudFlare::DDNS->new( # Required user => $CF_USER, apikey => $CF_KEY, zones => $ZONE_CONF, # Optional verbose => $VERB_LVL ); The zones specifies the zones and records which will be updated. Its structure is as follows # Array of [ # Hashes of { # DNS Zone zone => $zone_name_1, # Domains to be updated in this zone domains => [ $domain_1, ..., $domain_n ] }, ... { zone => $zone_name_n, domains => [ $domain_1, ..., $domain_n ] } ] Each domain is an A record within a zone or undef for the zone itself =head2 update Updates CloudFlare DNS with the current IP address if necessary $ddns->update =head1 BUGS Please report any bugs or feature requests to C, or through the web interface at L =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan =head1 SUPPORT =head2 Perldoc You can find documentation for this module with the perldoc command. perldoc Net::DNS::CloudFlare::DDNS =head2 Websites The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources. =over 4 =item * MetaCPAN A modern, open-source CPAN search engine, useful to view POD in HTML format. L =back =head2 Email You can email the author of this module at C asking for help with any problems you have. =head2 Source Code The code is open to the world, and available for you to hack on. Please feel free to browse it and play with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull from your repository :) L git clone git://github.com/pwr22/Net-DNS-CloudFlare-DDNS.git =head1 BUGS Please report any bugs or feature requests on the bugtracker website https://github.com/pwr22/Net-DNS-CloudFlare-DDNS/issues When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 CONTRIBUTOR =for stopwords Peter Roberts Peter Roberts =head1 AUTHOR Peter Roberts =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2016 by Peter Roberts. This is free software, licensed under: The MIT (X11) License =cut DDNS000755001751001751 012676225675 21761 5ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/lib/Net/DNS/CloudFlareTypes.pm100644001751001751 500312676225675 23561 0ustar00peterpeter000000000000Net-DNS-CloudFlare-DDNS-v0.63.1/lib/Net/DNS/CloudFlare/DDNSpackage Net::DNS::CloudFlare::DDNS::Types; # ABSTRACT: Types for Net::DNS::CloudFlare::DDNS use Modern::Perl '2012'; use autodie ':all'; no indirect 'fatal'; use namespace::autoclean; use Type::Library -base; # Theres a bug about using undef as a hashref before this version use Type::Utils 0.039_12 -all; our $VERSION = 'v0.63.1'; # VERSION class_type 'CloudFlare::Client'; class_type 'LWP::UserAgent'; 1; # End of Net::DNS::CloudFlare::DDNS::Types __END__ =pod =encoding UTF-8 =head1 NAME Net::DNS::CloudFlare::DDNS::Types - Types for Net::DNS::CloudFlare::DDNS =head1 VERSION version v0.63.1 =head1 SYNOPSIS Provides types used in Net::DNS::CloudFlare::DDNS use Net::DNS::CloudFlare::DDNS::Types 'CloudFlareClient'; =head1 SEE ALSO Please see those modules/websites for more information related to this module. =over 4 =item * L =back =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan =head1 SUPPORT =head2 Perldoc You can find documentation for this module with the perldoc command. perldoc Net::DNS::CloudFlare::DDNS =head2 Websites The following websites have more information about this module, and may be of help to you. As always, in addition to those websites please use your favorite search engine to discover more resources. =over 4 =item * MetaCPAN A modern, open-source CPAN search engine, useful to view POD in HTML format. L =back =head2 Email You can email the author of this module at C asking for help with any problems you have. =head2 Source Code The code is open to the world, and available for you to hack on. Please feel free to browse it and play with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull from your repository :) L git clone git://github.com/pwr22/Net-DNS-CloudFlare-DDNS.git =head1 BUGS Please report any bugs or feature requests on the bugtracker website https://github.com/pwr22/Net-DNS-CloudFlare-DDNS/issues When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 AUTHOR Peter Roberts =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2016 by Peter Roberts. This is free software, licensed under: The MIT (X11) License =cut