You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SH-Deployer/apps/SA-ITOA/bin/itsi_at_saved_search_rewrit...

131 lines
5.7 KiB

# Copyright (C) 2005-2024 Splunk Inc. All Rights Reserved.
import sys
import logging
from splunk.clilib.bundle_paths import make_splunkhome_path
sys.path.append(make_splunkhome_path(['etc', 'apps', 'SA-ITOA', 'lib']))
sys.path.append(make_splunkhome_path(['etc', 'apps', 'SA-ITOA', 'lib', 'SA_ITOA_app_common']))
import itsi_path
from ITOA.itoa_common import post_splunk_user_message, modular_input_should_run, is_feature_enabled
from ITOA.mod_input_utils import skip_run_during_migration
from itsi.searches.itsi_at_search import ItsiAtSearch
from ITOA.setup_logging import getLogger4ModInput
from ITOA.storage.itoa_storage import ITOAStorage
from SA_ITOA_app_common.solnlib.modular_input import ModularInput
# Flag used for generating the restartless testing logs only once.
modular_input_reloaded = False
class ItsiAtSavedSearchRewriter(ModularInput):
'''
Modular input to rewrite AT saved searches based on the feature flags
itsi-at-outlier-detection and itsi-high-scale-at.
'''
title = "IT Service Intelligence AT search rewriter"
description = "Updates AT saved searches with itsiat/applyat command and high scale AT" \
"when itsi-at-outlier-detection and/or itsi-high-scale-at flags are switched."
handlers = None
app = 'SA-ITOA'
name = 'itsi_at_saved_search_rewriter'
use_single_instance = True
use_kvstore_checkpointer = False
use_hec_event_writer = False
def extra_arguments(self):
return [
{
'name' : "log_level",
'title' : "Logging Level",
'description' : "This is the level at which the modular input will log data."
}
]
def show_message(self, message):
post_splunk_user_message(message, session_key=self.session_key)
@skip_run_during_migration
def do_run(self, stanzas):
"""
This is the method called by splunkd when mod input is enabled.
@param stanzas: config stanzas passed down by splunkd
"""
if len(stanzas) == 0:
# The feature is disabled, no stanzas are present.
return
logger = getLogger4ModInput(stanzas)
# Single instance mode for safety only, so we only want the first stanza
stanza_name = next(iter(stanzas.keys()))
stanza_config = next(iter(stanzas.values()))
# log the message for restartless upgrade testing which can be useful while debugging.
global modular_input_reloaded
if not modular_input_reloaded:
logger.info(f"Restartless upgrade - Reloaded modular input {stanza_name}")
modular_input_reloaded = True
if not modular_input_should_run(self.session_key, logger=logger):
logger.info("Modular input will not run on this node.")
return
level = stanza_config.get("log_level", 'INFO').upper()
if level not in ["ERROR", "WARN", "WARNING", "INFO", "DEBUG"]:
level = "INFO"
logger.setLevel(logging.getLevelName(level))
logger.info("Running itsi_at_saved_search_rewriter modular input.")
is_high_scale_at_enabled = is_feature_enabled('itsi-high-scale-at', self.session_key)
is_entity_level_at_enabled = is_feature_enabled('itsi-entity-level-adaptive-thresholding', self.session_key)
ck = self.checkpointer
stored_high_scale_at_feature_status_key = stanza_name + 'id' + 'itsi-high-scale-at'
stored_high_scale_at_feature_status = bool(ck.get(stored_high_scale_at_feature_status_key))
stored_entity_level_at_feature_status_key = stanza_name + 'id' + 'itsi-entity-level-adaptive-thresholding'
stored_entity_level_at_feature_status = bool(ck.get(stored_entity_level_at_feature_status_key))
# Only run Mod Input if checkpoint value and feature flag value doesn't match
# Mod input for entity Level AT should only run if High Scale AT is enabled
if (is_high_scale_at_enabled == stored_high_scale_at_feature_status):
if stored_entity_level_at_feature_status == is_entity_level_at_enabled:
logger.info("Feature flags for High Scale AT and Entity Level AT were not updated. No need to rewrite AT saved searches.")
return
elif not is_high_scale_at_enabled:
logger.error("High Scale AT is disabled. Cannot start process for Entity Level AT feature flip.")
raise
if not is_high_scale_at_enabled and is_entity_level_at_enabled:
logger.error("Only High Scale AT feature flag disabled. Please also Disable Entity Level AT feature flag to proceed")
raise
kvstore = ITOAStorage()
if not kvstore.wait_for_storage_init(self.session_key):
raise Exception("KVStore not initialized. Savedsearch rewriter for High Scale AT and Entity Level AT failed.")
try:
# Call utility method to convert saved searches
failed_searches = ItsiAtSearch(self.session_key).rewrite_saved_searches()
if len(failed_searches) == 0:
logger.info("AT saved searches were rewritten successfully.")
ck.update(stored_high_scale_at_feature_status_key, int(is_high_scale_at_enabled))
ck.update(stored_entity_level_at_feature_status_key, int(is_entity_level_at_enabled))
else:
logger.info("AT saved searches rewrite failed for searches: %s" % failed_searches)
except Exception as e:
logger.exception("AT saved searches rewrite failed with an exception: %s ", e)
logger.info("Exiting itsi_at_saved_search_rewriter modular input.")
return
if __name__ == "__main__":
worker = ItsiAtSavedSearchRewriter()
worker.execute()
sys.exit(0)