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:
472
zonemaster-cli/script/zonemaster-cli
Executable file
472
zonemaster-cli/script/zonemaster-cli
Executable file
@@ -0,0 +1,472 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use 5.14.2;
|
||||
use warnings;
|
||||
|
||||
use Zonemaster::CLI;
|
||||
use File::Spec;
|
||||
use autodie;
|
||||
|
||||
sub read_conf_file {
|
||||
# Returns list of command line parameters. List can be empty.
|
||||
my ( $conf_file ) = @_;
|
||||
my @lines;
|
||||
open my $fh, '<', $conf_file;
|
||||
while ( <$fh> ) {
|
||||
chomp;
|
||||
next if /^\s*$/;
|
||||
next if /^\s*#/;
|
||||
push @lines, $_;
|
||||
}
|
||||
return @lines;
|
||||
}
|
||||
|
||||
# Load default arguments from file in home directory, if any
|
||||
# This must be loaded before any global file to make the local
|
||||
# file take precedence
|
||||
my $home_dir = ( ( getpwuid( $< ) )[7] ) || $ENV{HOME};
|
||||
my $home_conf_file = File::Spec->catfile( $home_dir, '.zonemaster', 'cli.args' );
|
||||
|
||||
if ( -r $home_conf_file ) {
|
||||
my @lines = read_conf_file( $home_conf_file );
|
||||
unshift @ARGV, @lines;
|
||||
}
|
||||
|
||||
# Load default arguments from global file, if any
|
||||
my @global_conf = ( '/etc/zonemaster/cli.args', '/usr/local/etc/zonemaster/cli.args' ); # Order is significant.
|
||||
my $global_conf_file;
|
||||
|
||||
for my $p ( @global_conf ) {
|
||||
if ( -e $p and -r $p ) {
|
||||
$global_conf_file = $p;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined $global_conf_file ) {
|
||||
my @lines = read_conf_file( $global_conf_file );
|
||||
unshift @ARGV, @lines;
|
||||
|
||||
}
|
||||
|
||||
eval {
|
||||
my $exitstatus = Zonemaster::CLI->run( @ARGV );
|
||||
exit $exitstatus;
|
||||
};
|
||||
|
||||
print STDERR $@;
|
||||
exit $Zonemaster::CLI::EXIT_GENERIC_ERROR;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zonemaster-cli - run Zonemaster tests from the command line
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
zonemaster-cli [--help | --version | --list-tests]
|
||||
zonemaster-cli [OPTIONS] --dump-profile
|
||||
zonemaster-cli [OPTIONS] DOMAINNAME
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<zonemaster-cli> is a command-line interface to the Zonemaster test engine.
|
||||
It takes instructions the user provides as command line arguments, transforms
|
||||
them into suitable API calls to the engine, runs the test suite and prints the
|
||||
resulting messages. By default, the messages will be translated by the engine's
|
||||
translation module, with the corresponding timestamp and logging level when
|
||||
printed. See the available options below.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=head2 Special Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-h>, B<--help>
|
||||
|
||||
Print brief usage information and exit.
|
||||
(run `man zonemaster-cli` for the full manual page)
|
||||
|
||||
=item B<--version>
|
||||
|
||||
Print version information and exit.
|
||||
|
||||
=for :man The printed version numbers are the versions of this program as well as the ones from the underlying
|
||||
Zonemaster test engine.
|
||||
|
||||
=item B<--list-tests>
|
||||
|
||||
Print all test cases listed in the test modules, then exit.
|
||||
|
||||
=item B<--dump-profile>
|
||||
|
||||
Print the effective profile used in JSON format, then exit.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Testing Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--test>=EXPR
|
||||
|
||||
Specify which test cases to run by setting the C<test_cases> property in the profile.
|
||||
The EXPR is a flexible expression consisting of terms (individual test cases, test
|
||||
modules, or all) and operators (C<+> to add, C<-> to remove).
|
||||
For details, see C<man zonemaster-cli>.
|
||||
|
||||
=begin :man
|
||||
|
||||
An EXPR starting with a term (e.g., C<all>, C<nameserver01>) I<replaces>
|
||||
the current selection.
|
||||
An EXPR starting with an operator (C<+> or C<->) I<modifies> the current selection.
|
||||
An empty EXPR (C<--test=>) does not modify the selection (i.e., it is a no-op).
|
||||
|
||||
Multiple C<--test> options may be specified; they are applied in the order they are given.
|
||||
When used together with the C<--profile>, the profile option is applied first.
|
||||
|
||||
Use C<--list-tests> to list all test cases and test modules in the default profile.
|
||||
|
||||
Examples:
|
||||
|
||||
=over 4
|
||||
|
||||
=item --test=B<all>
|
||||
|
||||
selects all test cases in the default profile, i.e. overrides any custom profile.
|
||||
|
||||
=item --test=B<nameserver>
|
||||
|
||||
selects all test cases in the Nameserver test module in the default profile.
|
||||
|
||||
=item --test=B<nameserver01>
|
||||
|
||||
selects only the Nameserver01 test case.
|
||||
|
||||
=item --test=B<dnssec-dnssec05>
|
||||
|
||||
selects all DNSSEC test cases except DNSSEC05.
|
||||
|
||||
=item --test=B<all-nameserver+nameserver03>
|
||||
|
||||
selects all test cases, excludes the Nameserver test cases, and adds back
|
||||
Nameserver03.
|
||||
|
||||
=item --test=B<-dnssec>
|
||||
|
||||
removes all DNSSEC test cases from the selection.
|
||||
|
||||
=item --test=B<+syntax01+syntax02>
|
||||
|
||||
adds the Syntax01 and Syntax02 test cases to the selection.
|
||||
|
||||
=item --test=
|
||||
|
||||
empty value is valid, but does not change the selection of test cases
|
||||
Specifying C<--test=> without an argument is a no-op.
|
||||
Having this possibility may come in handy when invoking zonemaster-cli from scripts.
|
||||
|
||||
=back
|
||||
|
||||
=end :man
|
||||
|
||||
=item B<--level>=LEVEL
|
||||
|
||||
Specify the minimum level of a message to be printed.
|
||||
(default: NOTICE)
|
||||
|
||||
=for :man Messages with this level
|
||||
(or higher) will be printed. The levels are, from highest to lowest:
|
||||
CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG, DEBUG2 and DEBUG3.
|
||||
The lowest three levels (DEBUG) add a significant amount of messages to be shown.
|
||||
They reveal some of the internal workings of the test engine, and are probably
|
||||
not useful for most users.
|
||||
|
||||
=begin :man
|
||||
|
||||
=item B<--stop-level>=LEVEL
|
||||
|
||||
Specify the minimum severity level after which the testing suite is terminated.
|
||||
(default: the empty string)
|
||||
|
||||
=for :man When set to the empty string, testing is allowed to complete normally
|
||||
no matter what messages are emitted.
|
||||
|
||||
=for :man The levels are, from highest to lowest: CRITICAL, ERROR, WARNING, NOTICE,
|
||||
INFO, DEBUG, DEBUG2 and DEBUG3.
|
||||
|
||||
=end :man
|
||||
|
||||
=item B<--[no-]progress>
|
||||
|
||||
Print an activity indicator ("spinner").
|
||||
(default: enabled if the process' standard output is a TTY)
|
||||
|
||||
=for :man Useful to know that something is happening during a run.
|
||||
|
||||
=item B<--[no-]ipv4>, B<--[no-]ipv6>
|
||||
|
||||
Enable or disable queries over IPv4 or IPv6.
|
||||
(default: both enabled)
|
||||
|
||||
=begin :man
|
||||
|
||||
=item B<--sourceaddr4>=IPADDR, B<--sourceaddr6>=IPADDR
|
||||
|
||||
Set IPv4 or IPv6 source address for DNS queries.
|
||||
|
||||
=for :man Setting an address not correctly configured on a local network interface
|
||||
fails silently.
|
||||
|
||||
=end :man
|
||||
|
||||
=item B<--profile>=FILE
|
||||
|
||||
Override the Zonemaster Engine default profile data with values from
|
||||
the given profile JSON file.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Formatting Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--[no-]json>
|
||||
|
||||
Print results as JSON instead of human language.
|
||||
(default: disabled)
|
||||
|
||||
=begin :man
|
||||
|
||||
=item B<--[no-]json-stream>
|
||||
|
||||
Stream the results as JSON.
|
||||
(default: disabled)
|
||||
|
||||
=for :man Useful to follow the progress in a machine-readable way.
|
||||
|
||||
=item B<--[no-]raw>
|
||||
|
||||
Print messages as raw dumps (message identifiers) instead of translating them
|
||||
to human language.
|
||||
|
||||
=end :man
|
||||
|
||||
=item B<--locale>=LOCALE
|
||||
|
||||
Specify which locale to be used by the translation system.
|
||||
(default: system locale or English)
|
||||
|
||||
=for :man If not given, the
|
||||
translation system itself will look at environment variables to try and guess.
|
||||
If the requested translation does not exist, it will fall back to the local
|
||||
locale, and if that does not exist either, to English.
|
||||
|
||||
=begin :man
|
||||
|
||||
=item B<--[no-]time>
|
||||
|
||||
Print the timestamp for each message.
|
||||
(default: enabled)
|
||||
|
||||
=item B<--[no-]show-level>
|
||||
|
||||
Print the severity level for each message.
|
||||
(default: enabled)
|
||||
|
||||
=item B<--[no-]show-module>
|
||||
|
||||
Print the name of the module which produced the message.
|
||||
(default: disabled)
|
||||
|
||||
=item B<--[no-]show-testcase>
|
||||
|
||||
Print the name of the test case (test case identifier) which produced the message.
|
||||
(default: disabled)
|
||||
|
||||
=end :man
|
||||
|
||||
=back
|
||||
|
||||
=begin :man
|
||||
|
||||
=head2 Summary Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--[no-]count>
|
||||
|
||||
Print a summary, at the end of a run, of the numbers of messages for each severity
|
||||
level that were logged during the run, as well as a count of each message tag.
|
||||
(default: disabled)
|
||||
|
||||
=item B<--[no-]nstimes>
|
||||
|
||||
Print a summary, at the end of a run, of various metrics related to the times
|
||||
(in milliseconds) each name server took to answer, as well as a count of the
|
||||
number of sent queries per name server.
|
||||
(default: disabled)
|
||||
|
||||
=item B<--[no-]elapsed>
|
||||
|
||||
Print elapsed time (in seconds) at end of a run.
|
||||
(default: disabled)
|
||||
|
||||
=back
|
||||
|
||||
=head2 Undelegated Test Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--ns>=DOMAINNAME, B<--ns>=DOMAINNAME/IPADDR
|
||||
|
||||
Provide information about a nameserver, for undelegated tests.
|
||||
|
||||
=for :man The argument
|
||||
must be either: (i) a domain name and an IP address, separated by a single
|
||||
slash character (/), or (ii) only a domain name, in which case a A and AAAA
|
||||
records lookup for that name is done in the live global DNS tree (unless
|
||||
overridden by --hints) and from which the results of that lookup will be used.
|
||||
|
||||
=for :man This switch can be given multiple times. As long as any of these switches
|
||||
are present, their aggregated content will be used as the
|
||||
entirety of the parent-side delegation information.
|
||||
|
||||
=item B<--ds>=KEYTAG,ALGORITHM,TYPE,DIGEST
|
||||
|
||||
Provide a DS record for undelegated testing (that is, a test where the
|
||||
delegating nameserver information is given via --ns switches).
|
||||
|
||||
=for :man The four pieces
|
||||
of data (keytag, algorithm, type, digest) should be in the same format they would
|
||||
have in a zone file.
|
||||
|
||||
=item B<--hints>=FILE
|
||||
|
||||
Name of a root hints file to override the defaults.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Cache Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--save>=FILE
|
||||
|
||||
Write the contents of the accumulated DNS packet cache to a file with the given name
|
||||
after the testing suite has finished running.
|
||||
|
||||
=item B<--restore>=FILE
|
||||
|
||||
Prime the DNS packet cache with the contents from the file with the given name
|
||||
before starting the testing suite.
|
||||
|
||||
=for :man The format of the file should be from one produced by the --save
|
||||
switch.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Deprecated Options
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--encoding>=ENCODING
|
||||
|
||||
Deprecated: Simply remove it from your usage. It is ignored.
|
||||
|
||||
=item B<--[no-]json-translate>
|
||||
|
||||
Deprecated since v2023.1, use --no-raw instead.
|
||||
|
||||
=for :man For streaming JSON output, include the translated message of the tag.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Option Aliases
|
||||
|
||||
These options are provided for compatibility with older scripts.
|
||||
The first two are aliases for C<--help>.
|
||||
The rest are aliases for their namesakes spelled with dash C<-> instead of
|
||||
underscore C<_>.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<-?>
|
||||
|
||||
=item B<--usage>
|
||||
|
||||
=item B<--dump_profile>
|
||||
|
||||
=item B<--[no-]json_stream>
|
||||
|
||||
=item B<--[no-]json_translate>
|
||||
|
||||
=item B<--list_tests>
|
||||
|
||||
=item B<--[no-]show_level>
|
||||
|
||||
=item B<--[no-]show_module>
|
||||
|
||||
=item B<--[no-]show_testcase>
|
||||
|
||||
=item B<--stop_level>=LEVEL
|
||||
|
||||
=back
|
||||
|
||||
=end :man
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
zonemaster-cli zonemaster.net
|
||||
|
||||
zonemaster-cli --test=delegation --level=info --no-time zonemaster.net
|
||||
|
||||
zonemaster-cli --test=delegation01 --level=debug zonemaster.net
|
||||
|
||||
zonemaster-cli --list-tests
|
||||
|
||||
=head1 PROFILES
|
||||
|
||||
The testing and result analysis performed by Zonemaster Engine is always
|
||||
guided by a profile.
|
||||
Zonemaster Engine has a default profile with sensible defaults.
|
||||
Zonemaster CLI allows users to override the default profile data with
|
||||
values from a profile JSON file with the C<--profile> option.
|
||||
For details on profiles and how they are represented in files, see
|
||||
L<Zonemaster::Engine::Profile>.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
If there is a readable file F</etc/zonemaster/cli.args> (Linux style), each line
|
||||
in that file will be prepended as an argument on the command line. If no
|
||||
F</etc/zonemaster/cli.args> is found (or is not readable) but
|
||||
F</usr/local/etc/zonemaster/cli.args> (FreeBSD style) is found and readable then
|
||||
that file will be used instead. Only one global file is loaded.
|
||||
|
||||
If there is a readable file F<.zonemaster/cli.args> in the user's home
|
||||
directory, it will be used in the same way even when a global file has been
|
||||
loaded. Any argument in user's F<cli.args> will override the same argument in the
|
||||
global config file.
|
||||
|
||||
For example, if one would like to by default run with the log
|
||||
level set to DEBUG and with translation to human-readable messages turned off,
|
||||
one could put this in the config file:
|
||||
|
||||
--raw
|
||||
--level=DEBUG
|
||||
|
||||
Only one argument per line. If the argument has a value there must be a "="
|
||||
between argument and value. A line starting with "#" is a comment. Comments
|
||||
cannot be added on lines with arguments.
|
||||
|
||||
Any arguments actually given on the command line will override what is in any of
|
||||
the loaded config files.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
More complete documentation on Zonemaster and its tests can be found on
|
||||
L<https://doc.zonemaster.net>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Calle Dybedahl <calle@init.se> and others from the Zonemaster project
|
||||
Reference in New Issue
Block a user