import json import logging import os import splunk.clilib.bundle_paths as bundle_paths import splunk.clilib.cli_common as comm from splunk.appbuilder import PACKAGE_PATH logger = logging.getLogger('splunk.spl2') FILELOCK_SERVICE_FAILED = "Service temporarily unavailable. Retry in 30 seconds." DOWNLOAD_MODULES_ENDPOINT = "/spl2/modules/download?app={app_name}" def sync_spl2_objects(handler_args, object_type, session_key, app_name): if object_type == "spl2-modules": dest = handler_args.get('dest', ["default"])[0] module_filter = [] arg_data = handler_args.data if 'filter' in arg_data and arg_data['filter'][0] is not None: for entry in arg_data['filter'][0].split(','): entry = entry.strip() if entry: module_filter.append(entry) app_modules = _get_all_modules(app_name, session_key) if not app_modules: logger.debug("No SPL2 modules found for app '{}'".format(app_name)) return bundle_paths.maybe_makedirs(PACKAGE_PATH, throw_exceptions=True) # TODO: Add concurrency mechanism - SCP-69093 create_module_files(app_name, dest, app_modules, module_filter) else: raise NotImplementedError("No handler for object_type {}".format(object_type)) def create_module_files(app, dest, modules, module_filter): app_path = bundle_paths.get_bundle(app).location() temp_path = os.path.join(PACKAGE_PATH, 'SPL2_DELETEME_' + app) spl2_path = os.path.join(app_path, dest, "data", "spl2") # delete stale temp_path if exists from previous CLI invoke and re-create dirs bundle_paths.safe_remove(temp_path) bundle_paths.maybe_makedirs(temp_path) # if ..app/{dest}/data/spl2 exists, copy all contents to temp_path if os.path.lexists(spl2_path): comm.mergeDirs(spl2_path, temp_path) # delete all .spl2 files from temp_path _delete_spl2_modules(temp_path) # write module files to the temp_path _write_module_files(temp_path, modules, module_filter) # remove ..app/{dest}/data/spl2 and mv temp_path contents to /data/spl2 bundle_paths.safe_remove(spl2_path) comm.moveItem(temp_path, spl2_path) logger.info("Moved downloaded modules to {}".format(spl2_path)) def _write_module_files(des, modules, module_filter): modules_written = [] for module in modules: name = module['name'] dirs = module['namespace'].split('.')[2:] # remove apps.