App-ElasticSearch-Utilities

 view release on metacpan or  search on metacpan

scripts/es-apply-settings.pl  view on Meta::CPAN

#!perl
# PODNAME: es-apply-settings.pl
# ABSTRACT: Run to apply a JSON list of settings to indexes matching a pattern
use strict;
use warnings;

use App::ElasticSearch::Utilities qw(:all);
use CLI::Helpers qw(:all);
use JSON::MaybeXS;
use Getopt::Long qw(:config no_ignore_case no_ignore_case_always);
use Pod::Usage;
use Test::Deep qw( cmp_details deep_diag subhashof );

#------------------------------------------------------------------------#
# Argument Collection
my %opt;
GetOptions(\%opt,
    'skip-alias=s@',
    'close',
    'older',
    'no-skip|noskip',
    'no-diff|nodiff',
    # Basic options
    'help|h',
    'manual|m',
);

#------------------------------------------------------------------------#
# Documentations!
pod2usage(1) if $opt{help};
pod2usage(-exitstatus => 0, -verbose => 2) if $opt{manual};

#------------------------------------------------------------------------#

# Figure out the skipped aliases
my %SKIP = map { $_ => 1 } (
    qw( .hold .do_not_erase ),
    $opt{'skip-alias'} ? ( @{ $opt{'skip-alias'} } ) : (),
);

# Read JSON Settings
my $RawJSON = '';
$RawJSON .= $_ while <>;

my $settings = undef;
eval {
    $settings = decode_json $RawJSON;
};
if( my $err = $@ ) {
    output({color=>'red'}, "Invalid JSON structure passed, error was '$err'");
    debug('JSON Passed was:', $RawJSON);
    exit 1;
}
debug("Settings to apply");
debug_var($settings);

# Delete Indexes older than a certain point
my @indices = es_indices(older => $opt{older});
if ( !@indices ) {
    output({color=>"red"}, "No matching indices found.");
    exit 1;
}
# Loop through the indices and take appropriate actions;
foreach my $index (sort @indices) {
    verbose("$index:  evaluated");

    my $info = es_request($index);
    next unless $info->{$index};
    my $meta = $info->{$index};

    # Only safety check when not forced
    if( !$opt{'no-skip'} ) {
        my $skipped;
        foreach my $alias ( keys %{ $meta->{aliases} } ) {
            $skipped = $alias if exists $SKIP{$alias};
            last if defined $skipped;
        }
        if( defined $skipped ) {
            output({color=>'magenta'}, " ~ Skipped $index due to protected alias '$skipped', use --no-skip to skip this safety check");
            next;
        }
    }

    # Check for settings first
    if( !$opt{'no-diff'} ) {
        # Since both, either, or neither can be flattened, flatten
        my $current = es_flatten_hash( $meta->{settings} );
        my $desired = es_flatten_hash( $settings );
        my ($ok,$stack) = cmp_details($desired, subhashof($current));
        if( $ok ) {
            output({color=>'cyan'}, " ~ Skipped $index as it already contains those settings, use --no-diff to apply without this check");
            next;
        }
        else {
            debug(deep_diag($stack));
        }
    }

scripts/es-apply-settings.pl  view on Meta::CPAN

See also the "CONNECTION ARGUMENTS" and "INDEX SELECTION ARGUMENTS" sections from App::ElasticSearch::Utilities.

From CLI::Helpers:

    --data-file         Path to a file to write lines tagged with 'data => 1'
    --tags              A comma separated list of tags to display
    --color             Boolean, enable/disable color, default use git settings
    --verbose           Incremental, increase verbosity (Alias is -v)
    --debug             Show developer output
    --debug-class       Show debug messages originating from a specific package, default: main
    --quiet             Show no output (for cron)
    --syslog            Generate messages to syslog as well
    --syslog-facility   Default "local0"
    --syslog-tag        The program name, default is the script name
    --syslog-debug      Enable debug messages to syslog if in use, default false
    --nopaste           Use App::Nopaste to paste output to configured paste service
    --nopaste-public    Defaults to false, specify to use public paste services
    --nopaste-service   Comma-separated App::Nopaste service, defaults to Shadowcat

=head1 DESCRIPTION

This script allows you to change index settings on indexes whose name matches the specified pattern.

Usage:

    $ es-apply-settings.pl --local --pattern logstash-*
    > { "index.routing.allocation.exclude.ip": "192.168.10.120" }

Or specify a file containing the settings

    $ es-apply-settings.pl --local --pattern logstash-* settings.json

=head1 OPTIONS

=over 8

=item B<help>

Print this message and exit

=item B<manual>

Print this message and exit

=item B<close>

B<IMPORTANT>: Settings are not dynamic, and the index needs to closed to have
the settings applied.  If this is set, the index will be re-opened before moving to the
next index.

=item B<older>

When this option is used along with the --days option the the setting will only be applied
to indexs that are older than the days specified.

    es-apply-settings.pl --older --days 30 --pattern logstash-*

=item B<skip-alias>

Protected aliases, which if present will cause the application of settings to
be skipped for a particular index.  The aliases C<.hold> and C<.do_not_erase>
will always be skipped.

=item B<no-skip>

Apply settings to all matching indexes, regardless of the protected aliases.

=item B<no-diff>

During a normal run, the settings you're requesting will be checked against the
indices and only indices with settings out of line with the desired settings
will be applied.  If for some reason you want to apply settings regardless of
the current state, using C<--no-diff> will disable the check and apply the
settings to every index in scope.

=back

=head1 AUTHOR

Brad Lhotsky <brad@divisionbyzero.net>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2024 by Brad Lhotsky.

This is free software, licensed under:

  The (three-clause) BSD License

=cut



( run in 1.076 second using v1.01-cache-2.11-cpan-39bf76dae61 )