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.
131 lines
5.7 KiB
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)
|