Files
Malin 8d4eaa1489 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>
2026-04-21 08:19:24 +02:00

110 lines
2.4 KiB
Perl
Executable File

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Zonemaster::Engine::Packet;
use JSON::PP;
use MIME::Base64;
use Module::Find qw[useall];
use Readonly;
use Scalar::Util qw[blessed];
useall 'Zonemaster::LDNS::RR';
# Decoder taken from Zonemaster::Engine::Nameserver->restore
Readonly my $decoder => JSON::PP->new->filter_json_single_key_object(
'Zonemaster::LDNS::Packet' => sub {
my ( $ref ) = @_;
## no critic (Modules::RequireExplicitInclusion)
my $obj = Zonemaster::LDNS::Packet->new_from_wireformat( decode_base64( $ref->{data} ) );
$obj->answerfrom( $ref->{answerfrom} );
$obj->timestamp( $ref->{timestamp} );
$obj->querytime( $ref->{querytime} );
return $obj;
}
)->filter_json_single_key_object(
'Zonemaster::Engine::Packet' => sub {
my ( $ref ) = @_;
return Zonemaster::Engine::Packet->new( { packet => $ref } );
}
);
# Decode input into packets
my @packets;
while ( my $line = <> ) {
my ( $name, $addr, $data ) = split( / /, $line, 3 );
my $tree = deserialize( $data );
push @packets, packets( $tree );
}
# Order packets chronologically
@packets = sort { $a->timestamp cmp $b->timestamp } @packets;
# Print delimited packets
my $delim = ";" x 78;
for my $packet ( @packets ) {
say $delim;
say $packet->string;
$delim = "\n" . ";" x 78;
}
=head1 NAME
data2dig - Export saved Zonemaster::Engine cache files to a dig format
=head1 SYNOPSIS
data2dig foo.data
=head1 DESCRIPTION
B<data2dig> exports saved Zonemaster::Engine cache files to human readable
format as chronologically ordered response packets in dig format.
=head1 SUBROUTINES
=head2 deserialize
Deserialize a string in Zonemaster::Engine saved cache format.
Returns a tree of nested HASHREFs with decoded Zonemaster::Engine::Packet
objects.
=cut
sub deserialize {
my $data = shift;
return $decoder->decode( $data );
}
=head2 packets
Return all Zonemaster::Engine::Packet objects from a tree of nested HASHREFs.
=cut
sub packets {
my ( $data ) = @_;
if ( ref $data eq 'HASH' && %{$data} && not blessed $data ) {
my @packets;
for my $key ( sort keys %$data ) {
push @packets, packets( $data->{$key} );
}
return @packets;
}
elsif ( blessed $data && $data->isa( 'Zonemaster::Engine::Packet' ) ) {
return ( $data );
}
else {
return ();
}
}