feat: add full Zonemaster stack with Docker and Spanish UI
- Clone all 5 Zonemaster component repos (LDNS, Engine, CLI, Backend, GUI) - Dockerfile.backend: 8-stage multi-stage build LDNS→Engine→CLI→Backend - Dockerfile.gui: Astro static build served via nginx - docker-compose.yml: backend (internal) + frontend (port 5353) - nginx.conf: root redirects to /es/, /api/ proxied to backend - zonemaster-gui/config.ts: defaultLanguage set to 'es' (Spanish) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
123
zonemaster-engine/t/util.t
Normal file
123
zonemaster-engine/t/util.t
Normal file
@@ -0,0 +1,123 @@
|
||||
use Test::More;
|
||||
use Test::Differences;
|
||||
use Test::Exception;
|
||||
|
||||
BEGIN { use_ok( 'Zonemaster::Engine::Util', qw( info name ns parse_hints ) ) }
|
||||
|
||||
isa_ok( ns( 'name', '::1' ), 'Zonemaster::Engine::Nameserver' );
|
||||
isa_ok( info( 'TAG', {} ), 'Zonemaster::Engine::Logger::Entry' );
|
||||
isa_ok( name( "foo.bar.com" ), 'Zonemaster::Engine::DNSName' );
|
||||
|
||||
subtest 'parse_hints()' => sub {
|
||||
my @cases = (
|
||||
{
|
||||
name => 'Cropped IANA hints',
|
||||
hints => <<EOF,
|
||||
; This file holds the information on root name servers needed to
|
||||
; -------- 8< --------
|
||||
. 3600000 NS A.ROOT-SERVERS.NET.
|
||||
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
|
||||
A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30
|
||||
;
|
||||
; FORMERLY NS1.ISI.EDU
|
||||
;
|
||||
. 3600000 NS B.ROOT-SERVERS.NET.
|
||||
B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201
|
||||
B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b
|
||||
; -------- 8< --------
|
||||
; End of file
|
||||
EOF
|
||||
expected => {
|
||||
'A.ROOT-SERVERS.NET' => [ '198.41.0.4', '2001:503:ba3e:0:0:0:2:30' ],
|
||||
'B.ROOT-SERVERS.NET' => [ '199.9.14.201', '2001:500:200:0:0:0:0:b' ],
|
||||
},
|
||||
},
|
||||
{
|
||||
name => 'Syntax error',
|
||||
hints => '(>_<)',
|
||||
error => qr/Unable to parse root hints/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden $TTL',
|
||||
hints => "\n\$TTL 3600",
|
||||
error => qr/Forbidden directive \$TTL/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden $INCLUDE',
|
||||
hints => "\n\$INCLUDE /etc/motd",
|
||||
error => qr/Forbidden directive \$INCLUDE/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden $ORIGIN',
|
||||
hints => "\n\$ORIGIN NET.",
|
||||
error => qr/Forbidden directive \$ORIGIN/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden $GENERATE',
|
||||
hints => "\n\$GENERATE 65-126 $ CNAME \$.64/26",
|
||||
error => qr/Forbidden directive \$GENERATE/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden CH class',
|
||||
hints => '. CH 3600000 NS A.ROOT-SERVERS.NET.',
|
||||
error => qr/Forbidden RR class CH/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden RR type SOA',
|
||||
hints => <<EOF,
|
||||
. 86400 SOA a.root-servers.net. nstld.verisign-grs.com. (
|
||||
2022093000 ; serial
|
||||
1800 ; refresh (30 minutes)
|
||||
900 ; retry (15 minutes)
|
||||
604800 ; expire (1 week)
|
||||
86400 ; minimum (1 day)
|
||||
)
|
||||
EOF
|
||||
error => qr/Forbidden RR type SOA/,
|
||||
},
|
||||
{
|
||||
name => 'Forbidden RR type TXT',
|
||||
hints => '. 3600000 TXT "B.ROOT-SERVERS.NET"',
|
||||
error => qr/Forbidden RR type TXT/,
|
||||
},
|
||||
{
|
||||
name => 'Wrong owner name',
|
||||
hints => 'NET. 3600000 NS A.ROOT-SERVERS.NET.',
|
||||
error => qr/Owner name for NS record must be "\."/,
|
||||
},
|
||||
{
|
||||
name => 'Missing address record',
|
||||
hints => '. 3600000 NS A.ROOT-SERVERS.NET.',
|
||||
error => qr/No address record found for NS A\.ROOT-SERVERS\.NET/,
|
||||
},
|
||||
{
|
||||
name => 'Orphan A record',
|
||||
hints => 'B.ROOT-SERVERS.NET. 3600000 A 199.9.14.201',
|
||||
error => qr/Owner name of A record does not match any NS RDATA/,
|
||||
},
|
||||
{
|
||||
name => 'Orphan AAAA record',
|
||||
hints => 'B.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:200::b',
|
||||
error => qr/Owner name of AAAA record does not match any NS RDATA/,
|
||||
},
|
||||
{
|
||||
name => 'Missing NS',
|
||||
hints => '',
|
||||
error => qr/No NS record found/,
|
||||
},
|
||||
);
|
||||
|
||||
for my $case ( @cases ) {
|
||||
if ( exists $case->{expected} ) {
|
||||
my $actual = parse_hints( $case->{hints} );
|
||||
eq_or_diff $actual, $case->{expected}, $case->{name};
|
||||
}
|
||||
else {
|
||||
throws_ok {
|
||||
parse_hints( $case->{hints} )
|
||||
} $case->{error}, $case->{name};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
done_testing;
|
||||
Reference in New Issue
Block a user