Skip to content

Commit

Permalink
do not combine operational flags
Browse files Browse the repository at this point in the history
  • Loading branch information
bodo-hugo-barwich committed Dec 23, 2022
2 parents 25ad203 + 3d96286 commit b66768b
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 16 deletions.
32 changes: 25 additions & 7 deletions lib/MetaCPAN/Role/Script.pm
Original file line number Diff line number Diff line change
Expand Up @@ -364,17 +364,32 @@ sub await {

sub are_you_sure {
my ( $self, $msg ) = @_;
my $iconfirmed = 0;

if (is_interactive) {
print colored( ['bold red'], "*** Warning ***: $msg" ), "\n";
my $answer = prompt
'Are you sure you want to do this (type "YES" to confirm) ? ';
my $answer
= prompt colored( ['bold red'], "*** Warning ***: $msg" ) . "\n"
. 'Are you sure you want to do this (type "YES" to confirm) ? ';
if ( $answer ne 'YES' ) {
print "bye.\n";
exit 0;
log_error {"Confirmation incorrect: '$answer'"};
print "Operation will be interruped!\n";

#Set System Error: 125 - ECANCELED - Operation canceled
$self->exit_code(125);
$self->handle_error( 'Operation canceled on User Request', 1 );
}
else {
log_info {'Operation confirmed.'};
print "alright then...\n";
$iconfirmed = 1;
}
print "alright then...\n";
}
else {
print colored( ['bold yellow'], "*** Warning ***: $msg" ) . "\n";
$iconfirmed = 1;
}

return $iconfirmed;
}

1;
Expand Down Expand Up @@ -424,7 +439,7 @@ This method uses the
L<C<Search::Elasticsearch::Client::2_0::Direct::ping()>|https://metacpan.org/pod/Search::Elasticsearch::Client::2_0::Direct#ping()>
method to verify the service availabilty and wait for C<arg_await_timeout> seconds.
When the service does not become available within C<arg_await_timeout> seconds it re-throws the
Exception from the C<Search::Elasticsearch::Client> and sets C< $! > to C< 112 >.
Exception from the C<Search::Elasticsearch::Client> and sets B<Exit Code> to C< 112 >.
The C<Search::Elasticsearch::Client> generates a C<"Search::Elasticsearch::Error::NoNodes"> Exception.
When the service is available it will populate the C<cluster_info> C<HASH> structure with the basic information
about the cluster.
Expand Down Expand Up @@ -462,6 +477,9 @@ See L<Method C<await()>>
Requests the user to confirm the operation with "I< YES >"
B<Exceptions:> When the operator input does not match "I< YES >" it will exit the Script
with Exit Code [125] (C<125 - ECANCELED - Operation canceled>).
=item C<handle_error( error_message[, die_always ] )>
Logs the string C<error_message> with the log function as fatal error.
Expand Down
94 changes: 86 additions & 8 deletions lib/MetaCPAN/Script/Mapping.pm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ has arg_deploy_mapping => (
documentation => 'delete index if it exists already',
);

has arg_delete_all => (
init_arg => 'all',
is => 'ro',
isa => Bool,
default => 0,
documentation =>
'delete ALL existing indices (only effective in combination with "--delete")',
);

has arg_verify_mapping => (
init_arg => 'verify',
is => 'ro',
Expand Down Expand Up @@ -146,15 +155,28 @@ has delete_from_type => (
sub run {
my $self = shift;

# Wait for the ElasticSearch Engine to become ready
if ( $self->await ) {
$self->delete_index if $self->arg_delete_index;
$self->create_index if $self->arg_create_index;
$self->update_index if $self->arg_update_index;
$self->copy_type if $self->copy_to_index;
$self->empty_type if $self->delete_from_type;
$self->list_types if $self->arg_list_types;

if ( $self->arg_deploy_mapping ) {
if ( $self->arg_delete_index ) {
$self->delete_index;
}
elsif ( $self->arg_create_index ) {
$self->create_index;
}
elsif ( $self->arg_update_index ) {
$self->update_index;
}
elsif ( $self->copy_to_index ) {
$self->copy_type;
}
elsif ( $self->delete_from_type ) {
$self->empty_type;
}
elsif ( $self->arg_deploy_mapping ) {
if ( $self->arg_delete_all ) {
$self->check_health;
$self->delete_all;
}
unless ( $self->deploy_mapping ) {
$self->print_error("Indices Re-creation has failed!");
$self->exit_code(1);
Expand All @@ -172,6 +194,10 @@ sub run {
}
}

if ( $self->arg_list_types ) {
$self->list_types;
}

if ( $self->arg_cluster_info ) {
$self->check_health;
$self->show_info;
Expand Down Expand Up @@ -213,6 +239,39 @@ sub delete_index {
$self->_delete_index($name);
}

sub delete_all {
my $self = $_[0];
my $runtime_environment = 'production';
my $is_development = 0;

$runtime_environment = $ENV{'PLACK_ENV'}
if ( defined $ENV{'PLACK_ENV'} );
$runtime_environment = $ENV{'MOJO_MODE'}
if ( defined $ENV{'MOJO_MODE'} );

$is_development = 1
if ( $runtime_environment eq 'development'
|| $runtime_environment eq 'testing' );

if ($is_development) {
my $name = undef;

$self->are_you_sure("ALL Indices will be deleted !!!");

foreach $name ( keys %{ $self->indices_info } ) {
$self->_delete_index($name);
}
}
else {
#Set System Error: 1 - EPERM - Operation not permitted
$self->exit_code(1);
$self->print_error("Operation not permitted!");
$self->handle_error(
"Operation not permitted in environment: $runtime_environment",
1 );
}
}

sub _delete_index {
my ( $self, $name ) = @_;

Expand Down Expand Up @@ -847,6 +906,7 @@ MetaCPAN::Script::Mapping - Script to set the index and mapping the types
# bin/metacpan mapping --show_cluster_info # show basic info about the cluster, indices and aliases
# bin/metacpan mapping --delete
# bin/metacpan mapping --delete --all # deletes ALL indices in the cluster
# bin/metacpan mapping --verify # compare deployed indices and aliases with project definitions
# bin/metacpan mapping --list_types
# bin/metacpan mapping --delete_index xxx
Expand Down Expand Up @@ -898,6 +958,24 @@ See L<Method C<mappings_valid()>>
See L<Method C<MetaCPAN::Role::Script::check_health()>>
=item Option C<--all>
This option is only effective in combination with Option C<--delete>.
It uses the information gathered by C<MetaCPAN::Role::Script::check_health()> to delete
B<ALL> indices in the I<ElasticSearch> Cluster.
This option is usefull to reconstruct a broken I<ElasticSearch> Cluster
bin/metacpan mapping --delete --all
B<Exceptions:> It will throw an exceptions when not performed in an development or
testing environment.
See L<Option C<--delete>>
See L<Method C<deploy_mapping()>>
See L<Method C<MetaCPAN::Role::Script::check_health()>>
=item Option C<--verify>
This option will request the index mappings from the I<ElasticSearch> Cluster and
Expand Down
2 changes: 1 addition & 1 deletion lib/MetaCPAN/Script/Runner.pm
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sub run {

# Display Exception Message in red
print colored( ['bold red'],
"*** EXECPTION [ $EXIT_CODE ] ***: " . $ex->{'message'} ),
"*** EXCEPTION [ $EXIT_CODE ] ***: " . $ex->{'message'} ),
"\n";
};

Expand Down
99 changes: 99 additions & 0 deletions t/lib/MetaCPAN/TestServer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ sub setup {

$self->es_client;

# Run the Delete Index Tests before mapping deployment
$self->test_delete_mappings;

# Deploy project mappings
$self->put_mappings;
}
Expand Down Expand Up @@ -351,6 +354,102 @@ sub prepare_user_test_data {
);
}

sub test_delete_mappings {
my $self = $_[0];

$self->test_delete_fails;
$self->test_delete_all;
}

sub test_delete_fails {
my $self = $_[0];

my $iexitcode;
my $irunok;

subtest 'delete all not permitted' => sub {

# mapping script - delete indices
{
local @ARGV = qw(mapping --delete --all);
local %ENV = (%ENV);

delete $ENV{'PLACK_ENV'};
delete $ENV{'MOJO_MODE'};

$irunok = MetaCPAN::Script::Runner::run;
$iexitcode = $MetaCPAN::Script::Runner::EXIT_CODE;
}

ok( !$irunok, "delete all fails" );
is( $iexitcode, 1, "Exit Code '1' - Permission Error" );
};
}

sub test_delete_all {
my $self = $_[0];

subtest 'delete all deletes unknown index' => sub {
subtest 'create index' => sub {
my $smockindexjson = q({
"mock_index" : {
"properties" : {
"mock_field" : {
"index" : "not_analyzed",
"ignore_above" : 2048,
"type" : "string"
}
}
}
});

local @ARGV = (
'mapping', '--create_index',
'mock_index', '--patch_mapping',
$smockindexjson
);

ok(
MetaCPAN::Script::Runner::run,
"creation 'mock_index' succeeds"
);
is( $MetaCPAN::Script::Runner::EXIT_CODE,
0, "Exit Code '0' - No Error" );
};
subtest 'info shows unknonwn index' => sub {
local @ARGV = ( 'mapping', '--show_cluster_info' );
my $mapping = MetaCPAN::Script::Mapping->new_with_options(
$self->_config );

ok( $mapping->run, "show info succeeds" );
is( $mapping->exit_code, 0, "Exit Code '0' - No Error" );

ok( defined $mapping->indices_info, 'Index Info built' );
ok( defined $mapping->indices_info->{'mock_index'},
'Unknown Index printed' );
};
subtest 'delete all succeeds' => sub {
local @ARGV = qw(mapping --delete --all);

ok( MetaCPAN::Script::Runner::run, "delete all succeeds" );
is( $MetaCPAN::Script::Runner::EXIT_CODE,
0, "Exit Code '0' - No Error" );
};
subtest 'info does not show unknown index' => sub {
local @ARGV = ( 'mapping', '--show_cluster_info' );
my $mapping = MetaCPAN::Script::Mapping->new_with_options(
$self->_config );

ok( $mapping->run, "show info succeeds" );
is( $mapping->exit_code, 0, "Exit Code '0' - No Error" );

ok( defined $mapping->indices_info, 'Index Info built' );
ok( !defined $mapping->indices_info->{'mock_index'},
'Unknown Index printed' );
};
};
}

sub test_mappings {
my $self = $_[0];

Expand Down
54 changes: 54 additions & 0 deletions t/script/mapping.t
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,60 @@ use MetaCPAN::Script::Mapping;

my $config = MetaCPAN::Script::Runner::build_config;

subtest 'create, delete index' => sub {
subtest 'create index' => sub {
my $smockindexjson = q({
"mock_index" : {
"properties" : {
"mock_field" : {
"type" : "string",
"ignore_above" : 2048,
"index" : "not_analyzed"
}
}
}
});
local @ARGV = (
'mapping', '--create_index',
'mock_index', '--patch_mapping',
$smockindexjson
);
my $mapping = MetaCPAN::Script::Mapping->new_with_options($config);

ok( $mapping->run, "creation 'mock_index' succeeds" );
is( $mapping->exit_code, 0, "Exit Code '0' - No Error" );
};
subtest 'info shows new index' => sub {
local @ARGV = ( 'mapping', '--show_cluster_info' );
my $mapping = MetaCPAN::Script::Mapping->new_with_options($config);

ok( $mapping->run, "show info succeeds" );
is( $mapping->exit_code, 0, "Exit Code '0' - No Error" );

ok( defined $mapping->indices_info, 'Index Info built' );
ok( defined $mapping->indices_info->{'mock_index'},
'Created Index printed' );
};
subtest 'delete index' => sub {
local @ARGV = ( 'mapping', '--delete_index', 'mock_index' );
my $mapping = MetaCPAN::Script::Mapping->new_with_options($config);

ok( $mapping->run, "deletion 'mock_index' succeeds" );
is( $mapping->exit_code, 0, "Exit Code '0' - No Error" );
};
subtest 'info does not show deleted index' => sub {
local @ARGV = ( 'mapping', '--show_cluster_info' );
my $mapping = MetaCPAN::Script::Mapping->new_with_options($config);

ok( $mapping->run, "show info succeeds" );
is( $mapping->exit_code, 0, "Exit Code '0' - No Error" );

ok( defined $mapping->indices_info, 'Index Info printed' );
ok( !defined $mapping->indices_info->{'mock_index'},
'Deleted Index not printed' );
};
};

subtest 'mapping verification succeeds' => sub {
local @ARGV = ( 'mapping', '--verify' );
my $mapping = MetaCPAN::Script::Mapping->new_with_options($config);
Expand Down

0 comments on commit b66768b

Please sign in to comment.