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.
210 lines
9.5 KiB
210 lines
9.5 KiB
# Copyright (C) 2005-2025 Splunk Inc. All Rights Reserved.
|
|
|
|
import json
|
|
import traceback
|
|
import http.client
|
|
|
|
import itsi_py3 # noqa
|
|
|
|
import splunk.rest as rest
|
|
from ITOA.setup_logging import getLogger
|
|
from ITOA.saved_search_utility import SavedSearch
|
|
from ITOA.storage.itoa_storage import ITOAStorage
|
|
from itsi.itsi_utils import SplunkMessageHandler
|
|
from splunk.clilib.bundle_paths import make_splunkhome_path
|
|
import urllib.parse
|
|
import platform
|
|
import subprocess
|
|
import sys
|
|
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']))
|
|
from SA_ITOA_app_common.solnlib.conf_manager import ConfManager
|
|
|
|
|
|
class ItsiEventGrouping(object):
|
|
|
|
def __init__(self, session_key, features):
|
|
self.logger = getLogger(logger_name='itsi.feature_flagging.UIViewAccessEnforcer')
|
|
self.session_key = session_key
|
|
self.features = features
|
|
self.RULE_ENGINE_MESSAGE_ID = 'RULE_ENGINE_MESSAGE_ID'
|
|
self.rules_engine_saved_search = SavedSearch.get_search(
|
|
self.session_key, 'itsi_event_grouping')
|
|
self.EVENT_GROUPING_URL = '/saved/searches/itsi_event_grouping?output_mode=json'
|
|
self.EVENTGROUP_COLLECTION = "/servicesNS/nobody/SA-ITOA/storage/collections/data/itsi_event_grouping_status/"
|
|
self.EVENT_GROUPING_OBJECT_URL = self.EVENTGROUP_COLLECTION + "itsi_event_grouping"
|
|
|
|
def manage_disable_or_enable(self):
|
|
if (self.features.get('itsi_event_grouping')):
|
|
if self._check_kv_store_value():
|
|
self._enable_rule_engine()
|
|
self._set_itsi_event_grouping_flag_status(False)
|
|
self._delete_message_for_rule_engine_state()
|
|
else:
|
|
try:
|
|
response, contents = rest.simpleRequest(
|
|
path=self.EVENT_GROUPING_URL,
|
|
sessionKey=self.session_key)
|
|
data = json.loads(contents)
|
|
disabled = data['entry'][0]["content"]['disabled']
|
|
if not disabled:
|
|
self._generate_message_for_rule_engine_state()
|
|
self._disable_rule_engine()
|
|
if not self._check_kv_store_value():
|
|
self._set_itsi_event_grouping_flag_status(True)
|
|
except Exception:
|
|
self.logger.error("Failed to accesss EVENT_GROUPING_URL {}".format(traceback.format_exc()))
|
|
raise
|
|
|
|
def _disable_rule_engine(self):
|
|
try:
|
|
self.rules_engine_saved_search['disabled'] = 1
|
|
SavedSearch.save_entity(self.session_key,
|
|
self.rules_engine_saved_search)
|
|
self.logger.info("Rule engine disabled")
|
|
except Exception:
|
|
self.logger.error("Failed to disable rule engine: {}".format(traceback.format_exc()))
|
|
raise
|
|
|
|
def _enable_rule_engine(self):
|
|
try:
|
|
self.rules_engine_saved_search['disabled'] = 0
|
|
SavedSearch.save_entity(self.session_key,
|
|
self.rules_engine_saved_search)
|
|
self.logger.info("Rule engine enabled")
|
|
except Exception:
|
|
self.logger.error("Failed to enable rule engine: {}".format(traceback.format_exc()))
|
|
raise
|
|
|
|
def _check_itsi_event_grouping_flag_status(self):
|
|
try:
|
|
response, contents = rest.simpleRequest(
|
|
path=self.EVENT_GROUPING_OBJECT_URL,
|
|
sessionKey=self.session_key)
|
|
contents = json.loads(contents)
|
|
return contents["itsi_event_grouping_flag_value"]
|
|
except Exception:
|
|
self.logger.error("Unable to check itsi_event_grouping_flag_value flag \
|
|
status from api : {}".format(traceback.format_exc()))
|
|
raise
|
|
|
|
def manage_nats_server(self):
|
|
cfm = ConfManager(self.session_key, 'SA-ITOA')
|
|
conf = cfm.get_conf('itsi_nats')
|
|
settings = conf.get('nats_settings')
|
|
suite_license_check = int(settings.get('require_license', 1))
|
|
if suite_license_check == 1:
|
|
nats_command = make_splunkhome_path(['etc', 'apps', 'SA-ITOA', 'bin', 'nats', 'nats-server'])
|
|
if platform.system().lower() == 'windows':
|
|
nats_command += '.exe'
|
|
if not (self.features.get('itsi_event_grouping')):
|
|
encoded_scripted_queue_input_name = urllib.parse.quote('$SPLUNK_HOME/etc/apps/SA-ITOA/bin/itsi_queue_re_init.py', safe='')
|
|
is_queue_mode_enabled = self.is_queue_mode_enabled(self.session_key,
|
|
encoded_scripted_queue_input_name)
|
|
if is_queue_mode_enabled:
|
|
self.logger.info("Stopping NATS server as ITSI license is missing")
|
|
shutdown_cmd = [nats_command, '--signal', 'quit']
|
|
subprocess.run(shutdown_cmd)
|
|
self.logger.info("Stopping Java Queue mode as ITSI license is missing")
|
|
self.disable_modular_input(self.session_key, encoded_scripted_queue_input_name,
|
|
'[$SPLUNK_HOME/etc/apps/SA-ITOA/bin/itsi_queue_re_init.py]')
|
|
|
|
def disable_modular_input(self, session_key, input_mode, script):
|
|
try:
|
|
response, content = rest.simpleRequest(
|
|
f"/servicesNS/nobody/SA-ITOA/data/inputs/script/{input_mode}?disabled=1",
|
|
sessionKey=session_key,
|
|
method="POST",
|
|
raiseAllErrors=True,
|
|
)
|
|
if response.status != 200:
|
|
raise Exception("Error while disabling the modular input")
|
|
|
|
except Exception as err:
|
|
self.logger.error('Error occurred while disabling the ' + script + ' scripted input: %s', str(err))
|
|
|
|
def is_queue_mode_enabled(self, session_key, input_name):
|
|
try:
|
|
response, content = rest.simpleRequest(
|
|
f"/servicesNS/nobody/SA-ITOA/data/inputs/script/{input_name}?output_mode=json",
|
|
sessionKey=session_key,
|
|
method="GET",
|
|
raiseAllErrors=True,
|
|
)
|
|
parsed_content = json.loads(content)
|
|
if not parsed_content["entry"][0]["content"]["disabled"]:
|
|
return True
|
|
else:
|
|
return False
|
|
except Exception as e:
|
|
self.logger.error('Error while validating the queue mode process : %s', str(e))
|
|
|
|
def _check_kv_store_value(self):
|
|
try:
|
|
if ITOAStorage().wait_for_storage_init(self.session_key):
|
|
response, contents = rest.simpleRequest(
|
|
path=self.EVENTGROUP_COLLECTION,
|
|
sessionKey=self.session_key)
|
|
contents = json.loads(contents)
|
|
if not contents:
|
|
response_obj, contents_obj = rest.simpleRequest(
|
|
path=self.EVENTGROUP_COLLECTION,
|
|
method="POST",
|
|
jsonargs=json.dumps({
|
|
"itsi_event_grouping_flag_value": True,
|
|
"_key": "itsi_event_grouping"
|
|
}),
|
|
sessionKey=self.session_key)
|
|
self.logger.info("itsi_event_grouping collection found empty posted \
|
|
object with itsi_event_grouping_flag_value:{}".format(True))
|
|
return self._check_itsi_event_grouping_flag_status()
|
|
except Exception:
|
|
self.logger.error("Unable to add object to collection \
|
|
itsi_event_grouping_status : {}".format(traceback.format_exc()))
|
|
raise
|
|
|
|
def _set_itsi_event_grouping_flag_status(self, status):
|
|
"""
|
|
This method maintains the state of itsi_event_grouping functionality. This method sets
|
|
itsi_event_grouping_flag_value to True or False on the basis of suite_state.
|
|
When user is in standard suite the flag itsi_event_grouping_flag_value will set to True.
|
|
When user is in Plus suite the itsi_event_grouping_flag_value value will set to False.
|
|
"""
|
|
response, contents = rest.simpleRequest(
|
|
path=self.EVENT_GROUPING_OBJECT_URL,
|
|
method="POST",
|
|
jsonargs=json.dumps({"itsi_event_grouping_flag_value": status}),
|
|
sessionKey=self.session_key)
|
|
|
|
if response.status == http.client.OK:
|
|
self.logger.info(
|
|
"Itsi_event_grouping flag status set to: " + str(status))
|
|
return
|
|
|
|
e = Exception(
|
|
"Failed to set itsi_event_grouping status to {}. Response={}".
|
|
format(status, response))
|
|
self.logger.exception(e)
|
|
raise e
|
|
|
|
def _generate_message_for_rule_engine_state(self):
|
|
messages = SplunkMessageHandler(self.session_key)
|
|
try:
|
|
message_text = (
|
|
"The 'itsi_event_grouping' search is disabled for IT Essentials Work. \
|
|
Enabling the search might cause an error.")
|
|
self.logger.info(message_text)
|
|
messages.post_or_update_message(self.RULE_ENGINE_MESSAGE_ID,
|
|
SplunkMessageHandler.INFO,
|
|
message_text)
|
|
except Exception:
|
|
self.logger.error("unable to generate message about itsi_event_grouping status")
|
|
|
|
def _delete_message_for_rule_engine_state(self):
|
|
messages = SplunkMessageHandler(self.session_key)
|
|
try:
|
|
messages.delete_message(self.RULE_ENGINE_MESSAGE_ID)
|
|
except Exception:
|
|
# the message might be already deleted by user
|
|
pass
|