mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-07-31 10:09:40 +00:00
test(ddns): cover Net::DNS version thresholds
This commit is contained in:
@@ -7,18 +7,20 @@ use lib "$FindBin::Bin/../../xCAT-server/lib";
|
||||
use lib "$FindBin::Bin/../../xCAT-server/lib/perl";
|
||||
use lib "$FindBin::Bin/../../perl-xCAT";
|
||||
|
||||
use File::Temp qw(tempfile);
|
||||
use Test::More;
|
||||
|
||||
$ENV{XCATCFG} ||= 'SQLite:/tmp';
|
||||
$ENV{XCATROOT} ||= "$FindBin::Bin/../../xCAT-server";
|
||||
|
||||
my $source_ddns_plugin =
|
||||
my $ddns_plugin_path =
|
||||
"$FindBin::Bin/../../xCAT-server/lib/xcat/plugins/ddns.pm";
|
||||
if ( -f $source_ddns_plugin ) {
|
||||
require $source_ddns_plugin;
|
||||
if ( -f $ddns_plugin_path ) {
|
||||
require $ddns_plugin_path;
|
||||
}
|
||||
else {
|
||||
require xCAT_plugin::ddns;
|
||||
$ddns_plugin_path = $INC{'xCAT_plugin/ddns.pm'};
|
||||
}
|
||||
|
||||
sub omapi_settings {
|
||||
@@ -41,6 +43,15 @@ local %XCATSITEVALS = (
|
||||
dhcpomshellpath => '/opt/site/bin/omshell',
|
||||
);
|
||||
|
||||
my @net_dns_versions = (
|
||||
[ '1.09', 0 ],
|
||||
[ '1.35', 0 ],
|
||||
[ '1.36', 1 ],
|
||||
[ '1.40', 1 ],
|
||||
[ '1.100', 1 ],
|
||||
[ '2.0', 1 ],
|
||||
);
|
||||
|
||||
my $defaults = omapi_settings();
|
||||
is(
|
||||
xCAT_plugin::ddns::ddns_key_contents(
|
||||
@@ -79,4 +90,193 @@ is(
|
||||
'custom DDNS key name and algorithm are rendered'
|
||||
);
|
||||
|
||||
subtest 'all Net::DNS thresholds share the dotted version policy' => sub {
|
||||
open( my $source_fh, '<', $ddns_plugin_path )
|
||||
or die "Unable to read $ddns_plugin_path: $!";
|
||||
local $/;
|
||||
my $source = <$source_fh>;
|
||||
close($source_fh)
|
||||
or die "Unable to close $ddns_plugin_path: $!";
|
||||
|
||||
my @raw_comparisons =
|
||||
( $source =~ /^(?!\s*#)[^\n]*(?:<|>=)\s*1\.36\b/gm );
|
||||
is( scalar(@raw_comparisons), 0,
|
||||
'no Net::DNS threshold uses Perl numeric comparison' );
|
||||
|
||||
my @policy_calls = ( $source =~ /net_dns_uses_keyfile\(\)/g );
|
||||
is( scalar(@policy_calls), 4,
|
||||
'all four Net::DNS threshold sites use the shared policy' );
|
||||
};
|
||||
|
||||
subtest 'Net::DNS threshold controls DDNS policy and signing' => sub {
|
||||
my $implicit_sha256 = {
|
||||
algorithm => 'hmac-sha256',
|
||||
algorithm_explicit => 0,
|
||||
};
|
||||
|
||||
foreach my $case (@net_dns_versions) {
|
||||
my ( $version, $uses_keyfile ) = @{$case};
|
||||
my $expected_algorithm = $uses_keyfile ? 'hmac-sha256' : 'hmac-md5';
|
||||
is(
|
||||
with_net_dns_version(
|
||||
$version,
|
||||
sub {
|
||||
xCAT_plugin::ddns::ddns_tsig_algorithm(
|
||||
{ omapi_settings => $implicit_sha256 }
|
||||
);
|
||||
}
|
||||
),
|
||||
$expected_algorithm,
|
||||
"Net::DNS $version selects the expected implicit algorithm"
|
||||
);
|
||||
|
||||
my $update = Local::DDNS::Update->new();
|
||||
with_net_dns_version(
|
||||
$version,
|
||||
sub {
|
||||
xCAT_plugin::ddns::ddns_sign_update(
|
||||
{
|
||||
omapi_settings => $defaults,
|
||||
privkey => 'legacy-secret',
|
||||
},
|
||||
$update
|
||||
);
|
||||
}
|
||||
);
|
||||
my $expected_call = $uses_keyfile
|
||||
? [ '/etc/xcat/ddns.key' ]
|
||||
: [ 'xcat_key', 'legacy-secret' ];
|
||||
is_deeply(
|
||||
$update->{sign_tsig_calls},
|
||||
[$expected_call],
|
||||
"Net::DNS $version signs through the expected interface"
|
||||
);
|
||||
|
||||
my $tracker = tie my %key_context, 'Local::DDNS::TrackingHash';
|
||||
with_net_dns_version(
|
||||
$version,
|
||||
sub {
|
||||
xCAT_plugin::ddns::ensure_ddns_key_file(\%key_context);
|
||||
}
|
||||
);
|
||||
is_deeply(
|
||||
$tracker->{fetches},
|
||||
$uses_keyfile ? ['privkey'] : [],
|
||||
"Net::DNS $version applies the expected keyfile write gate"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
subtest 'Net::DNS threshold controls named key reconciliation' => sub {
|
||||
foreach my $case (@net_dns_versions) {
|
||||
my ( $version, $uses_keyfile ) = @{$case};
|
||||
my ( $named_contents, $restartneeded ) =
|
||||
reconcile_named_key($version);
|
||||
my $expected_algorithm = $uses_keyfile ? 'hmac-sha256' : 'hmac-md5';
|
||||
|
||||
like(
|
||||
$named_contents,
|
||||
qr/^\s*algorithm\s+\Q$expected_algorithm\E\s*;/m,
|
||||
"Net::DNS $version keeps the expected named key algorithm"
|
||||
);
|
||||
is(
|
||||
$restartneeded ? 1 : 0,
|
||||
$uses_keyfile ? 0 : 1,
|
||||
"Net::DNS $version records the expected named restart state"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
done_testing();
|
||||
|
||||
sub with_net_dns_version {
|
||||
my ( $version, $code ) = @_;
|
||||
|
||||
local $Net::DNS::VERSION = $version;
|
||||
return $code->();
|
||||
}
|
||||
|
||||
sub reconcile_named_key {
|
||||
my ($version) = @_;
|
||||
|
||||
my ( $named_fh, $named_path ) = tempfile(UNLINK => 1);
|
||||
print {$named_fh}
|
||||
"options {\n};\n"
|
||||
. "key \"xcat_key\" {\n"
|
||||
. "\talgorithm hmac-sha256;\n"
|
||||
. "\tsecret \"legacy-secret\";\n"
|
||||
. "};\n";
|
||||
close($named_fh) or die "Unable to close $named_path: $!";
|
||||
|
||||
my $ctx = {
|
||||
omapi_settings => omapi_settings(),
|
||||
privkey => 'legacy-secret',
|
||||
zonesdir => '/tmp',
|
||||
dbdir => '/tmp',
|
||||
zonestotouch => {},
|
||||
adzones => {},
|
||||
dnsupdaters => [],
|
||||
adservers => [],
|
||||
restartneeded => 0,
|
||||
};
|
||||
|
||||
no warnings qw(redefine once);
|
||||
local *xCAT_plugin::ddns::get_conf = sub { return $named_path; };
|
||||
local *xCAT_plugin::ddns::ensure_ddns_key_file = sub { return; };
|
||||
local *xCAT::TableUtils::get_site_attribute = sub { return; };
|
||||
local *xCAT::Utils::runcmd = sub { return (); };
|
||||
local *xCAT::Utils::isAIX = sub { return 0; };
|
||||
local *xCAT::Utils::isLinux = sub { return 1; };
|
||||
local *xCAT::Table::new = sub {
|
||||
return bless {}, 'Local::DDNS::PasswdTable';
|
||||
};
|
||||
|
||||
with_net_dns_version(
|
||||
$version,
|
||||
sub { xCAT_plugin::ddns::update_namedconf( $ctx, 0 ); }
|
||||
);
|
||||
|
||||
open( my $result_fh, '<', $named_path )
|
||||
or die "Unable to read $named_path: $!";
|
||||
local $/;
|
||||
my $contents = <$result_fh>;
|
||||
close($result_fh) or die "Unable to close $named_path: $!";
|
||||
|
||||
return ( $contents, $ctx->{restartneeded} );
|
||||
}
|
||||
|
||||
{
|
||||
package Local::DDNS::Update;
|
||||
|
||||
sub new {
|
||||
return bless { sign_tsig_calls => [] }, shift;
|
||||
}
|
||||
|
||||
sub sign_tsig {
|
||||
my ( $self, @args ) = @_;
|
||||
push @{ $self->{sign_tsig_calls} }, \@args;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
package Local::DDNS::PasswdTable;
|
||||
|
||||
sub setAttribs {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
package Local::DDNS::TrackingHash;
|
||||
|
||||
sub TIEHASH {
|
||||
return bless { fetches => [] }, shift;
|
||||
}
|
||||
|
||||
sub FETCH {
|
||||
my ( $self, $key ) = @_;
|
||||
push @{ $self->{fetches} }, $key;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user