# Copyright (C) 2005-2025 Splunk Inc. All Rights Reserved. import time import json import sys import splunk import splunk.rest as rest 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'])) from ITOA.version_check import VersionCheck # noqa from ITOA.setup_logging import getLogger logger = getLogger(logger_name='itsi.itsi_version_compare') new_version = '4.20.0' class ServerInfoException(Exception): pass class VersionComparison(object): """ Class to compare versions between app and kvstore Singleton Class always returns the same instance across shared pages """ _instance = None is_version_consistent = False def __new__(cls): if cls._instance is None: cls._instance = super(VersionComparison, cls).__new__(cls) return cls._instance def should_render_migration_page(cls, session_key): retry = 0 # There is issue, if we call this function too soon, # we get 503 error which Service Unavailable # this means that KV store has not initialized yet # In the case of KVService, we get a 404 error while retry < 8: try: rsp, content = rest.simpleRequest( '/servicesNS/nobody/SA-ITOA/storage/collections/data/itsi_migration', sessionKey=session_key, raiseAllErrors=False, getargs={'output_mode': 'json'} ) if rsp.status != 503 and rsp.status != 404: break logger.info( 'KV store service is unavailable. Retry %d of 8.', (retry + 1)) except splunk.ResourceNotFound: # Catching this error case is a workaround until SPL-218406 is fixed logger.info( 'KV Service resource not found. Retry %d of 8.', (retry + 1)) time.sleep((retry + 0.5)**2) retry += 1 # KV store or KVService is not ready if rsp.status == 503 or rsp.status == 404: logger.error('Got bad status code %s. KV store failed to initialize, Please retry. - Aborting. ', rsp.status) raise ServerInfoException( 'Got bad status code %s - Aborting.' % rsp.status) if rsp.status == 200: try: json_data = json.loads(content) # fresh install loads the page if len(json_data) == 0: logger.info( 'Could not find the migration stanza. It seems to be a fresh installation.') return False else: json_data = sorted( json_data, key=lambda item: item['title']) old_version = json_data[-1]['itsi_latest_version'] if VersionCheck.compare(old_version, new_version) < 0: return True else: # If the KV store version is consistent, set is_version_consistent to True, once this happens, # no more request is needed anymore unless a restart cls.is_version_consistent = True return False except Exception: logger.exception( 'Failed to compare file system version and KV store version. Loading the page.') return False # any code that is other than 503 or 200 loads the page else: logger.error('Got bad non-200 status code %s and failed to fetch the current version. Loading the page.', rsp.status) return False