241 lines
5.6 KiB
Perl
241 lines
5.6 KiB
Perl
|
|
#!/usr/bin/env perl
|
||
|
|
|
||
|
|
use 5.14.2;
|
||
|
|
use warnings;
|
||
|
|
use strict;
|
||
|
|
|
||
|
|
use version; our $VERSION = version->declare("v1.0.1");
|
||
|
|
|
||
|
|
use Carp;
|
||
|
|
|
||
|
|
use English qw( -no_match_vars );
|
||
|
|
|
||
|
|
use Zonemaster::Engine::Profile;
|
||
|
|
use JSON::XS;
|
||
|
|
use Scalar::Util qw( reftype );
|
||
|
|
use File::Slurp;
|
||
|
|
use Getopt::Long;
|
||
|
|
use File::Basename;
|
||
|
|
use Clone qw(clone);
|
||
|
|
|
||
|
|
my $DEBUG = 0;
|
||
|
|
my $DEST_DIR = q{};
|
||
|
|
my $CONFIG_FILE = q{};
|
||
|
|
my $POLICY_FILE = q{};
|
||
|
|
|
||
|
|
my $scriptName = basename($PROGRAM_NAME);
|
||
|
|
my $dest_dir = q{./};
|
||
|
|
my $config_file = q{};
|
||
|
|
my $policy_file = q{};
|
||
|
|
|
||
|
|
process_options();
|
||
|
|
|
||
|
|
if ( $DEST_DIR ) {
|
||
|
|
$dest_dir = $DEST_DIR;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $CONFIG_FILE ) {
|
||
|
|
$config_file = $CONFIG_FILE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $POLICY_FILE ) {
|
||
|
|
$policy_file = $POLICY_FILE;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($DEBUG) {
|
||
|
|
print "Debug Mode set ON\n";
|
||
|
|
print "Destination directory : $dest_dir\n\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
#-------------------------------------------------
|
||
|
|
# STEP 0: Check Directory existence and Directory/Files permissions
|
||
|
|
#-------------------------------------------------
|
||
|
|
if ( ! -d $dest_dir ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
print "Directory $dest_dir does not exist.\n";
|
||
|
|
unless ( mkdir $dest_dir ) {
|
||
|
|
croak "Unable to create $dest_dir.";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! -w $dest_dir ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
print "Directory $dest_dir mode must be changed.\n";
|
||
|
|
unless ( chmod (oct(755), $dest_dir) ) {
|
||
|
|
croak "Cannot change directory mode.";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! $config_file ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
croak "A Config file must be provided.";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! -e $config_file ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
croak "Config file $config_file does not exists.";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! -r $config_file ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
croak "Config file $config_file is not readable.";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! $policy_file ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
croak "A Policy file must be provided.";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! -e $policy_file ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
croak "Policy file $policy_file does not exists.";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( ! -r $policy_file ) {
|
||
|
|
printf "(\"%s --help\" for help)\n", $scriptName;
|
||
|
|
croak "Policy file $policy_file is not readable.";
|
||
|
|
}
|
||
|
|
|
||
|
|
my $policy_json = read_file( $policy_file ) ;
|
||
|
|
my $policy = decode_json( $policy_json );
|
||
|
|
my $config_json = read_file( $config_file );
|
||
|
|
my $config = decode_json( $config_json );
|
||
|
|
|
||
|
|
my $default = Zonemaster::Engine::Profile->default;
|
||
|
|
my $profile = Zonemaster::Engine::Profile->new;
|
||
|
|
|
||
|
|
my %paths;
|
||
|
|
my %default_paths;
|
||
|
|
Zonemaster::Engine::Profile::_get_profile_paths(\%paths, $config);
|
||
|
|
Zonemaster::Engine::Profile::_get_profile_paths(\%default_paths, $default->{q{profile}});
|
||
|
|
delete $default_paths{ q{test_cases} };
|
||
|
|
delete $default_paths{ q{test_levels} };
|
||
|
|
|
||
|
|
#
|
||
|
|
# General options part
|
||
|
|
#
|
||
|
|
|
||
|
|
foreach my $property_name ( keys %default_paths ) {
|
||
|
|
my $value = Zonemaster::Engine::Profile::_get_value_from_nested_hash( $config, split /\./, $property_name );
|
||
|
|
if ( defined $value ) {
|
||
|
|
$profile->set( $property_name, $value );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#
|
||
|
|
# Test cases part
|
||
|
|
#
|
||
|
|
|
||
|
|
my @tc;
|
||
|
|
foreach my $tc ( @{ $default->get( q{test_cases} ) } ) {
|
||
|
|
if ( not defined $policy->{__testcases__}->{$tc} or $policy->{__testcases__}->{$tc} ) {
|
||
|
|
push @tc, $tc;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$profile->set( q{test_cases}, \@tc );
|
||
|
|
|
||
|
|
#
|
||
|
|
# Test levels part
|
||
|
|
#
|
||
|
|
|
||
|
|
my %tl;
|
||
|
|
foreach my $tl ( keys %{ $default->get( q{test_levels} ) } ) {
|
||
|
|
if ( exists $policy->{$tl} ) {
|
||
|
|
$tl{$tl} = clone $policy->{$tl};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$profile->set( q{test_levels}, \%tl );
|
||
|
|
|
||
|
|
my $filename = $dest_dir.q{/profile.json};
|
||
|
|
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
|
||
|
|
my $json = JSON::XS->new->canonical->pretty;
|
||
|
|
print $fh $json->encode( $profile->{q{profile}} );
|
||
|
|
close $fh;
|
||
|
|
|
||
|
|
sub process_options {
|
||
|
|
my ( $opt_dest, $opt_config, $opt_policy, $opt_help, $opt_debug, $opt_version );
|
||
|
|
|
||
|
|
GetOptions(
|
||
|
|
q{dest-dir=s} => \$opt_dest, # Dest directory for generated profile file
|
||
|
|
q{config=s} => \$opt_config, # Config File
|
||
|
|
q{policy=s} => \$opt_policy, # Policy file
|
||
|
|
q{help} => \$opt_help, # Print Usage
|
||
|
|
q{debug} => \$opt_debug, # Set Debug MODE
|
||
|
|
q{version} => \$opt_version, # Print Version
|
||
|
|
);
|
||
|
|
|
||
|
|
if ( $opt_debug ) {
|
||
|
|
$DEBUG = 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $opt_dest ) {
|
||
|
|
$DEST_DIR = $opt_dest;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $opt_config ) {
|
||
|
|
$CONFIG_FILE = $opt_config;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $opt_policy ) {
|
||
|
|
$POLICY_FILE = $opt_policy;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $opt_help ) {
|
||
|
|
Usage();
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $opt_version ) {
|
||
|
|
Version();
|
||
|
|
}
|
||
|
|
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
sub Usage {
|
||
|
|
my $_bold = "\e[1m";
|
||
|
|
my $_normal = "\e[0m";
|
||
|
|
my $_ul = "\e[4m";
|
||
|
|
my $scriptNameBlank = $scriptName;
|
||
|
|
$scriptNameBlank =~ s/./ /smxg;
|
||
|
|
|
||
|
|
print << "EOM";
|
||
|
|
|
||
|
|
${_bold}NAME${_normal}
|
||
|
|
${scriptName} - Convert Config/Policy files into Profile file.
|
||
|
|
|
||
|
|
${_bold}SYNOPSIS${_normal}
|
||
|
|
${scriptName} [ --help ] [ --dest-dir=${_ul}alternate_destination_directory${_normal} ] [ --config=${_ul}config_file${_normal} ] [ --policy=${_ul}policy_file${_normal} ] [ --debug ]
|
||
|
|
|
||
|
|
|
||
|
|
${_bold}OPTIONS${_normal}
|
||
|
|
--help
|
||
|
|
Print this message and exit.
|
||
|
|
|
||
|
|
--config
|
||
|
|
Name of the Config file to convert.
|
||
|
|
|
||
|
|
--policy
|
||
|
|
Name of the Policy file to convert.
|
||
|
|
|
||
|
|
--dest-dir
|
||
|
|
Name of an alternate directory to save generated profile file.
|
||
|
|
${_bold}DEFAULT${_normal} is $dest_dir.
|
||
|
|
|
||
|
|
--debug
|
||
|
|
Set Debug mode ON.
|
||
|
|
|
||
|
|
--version
|
||
|
|
Print version of this program.
|
||
|
|
|
||
|
|
EOM
|
||
|
|
|
||
|
|
exit 0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
sub Version {
|
||
|
|
printf "%s %s\n", $scriptName, $VERSION;
|
||
|
|
exit 0;
|
||
|
|
}
|
||
|
|
|