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.
139 lines
5.2 KiB
139 lines
5.2 KiB
# Copyright (C) 2005-2024 Splunk Inc. All Rights Reserved.
|
|
|
|
|
|
import sys
|
|
import json
|
|
|
|
from splunk.clilib.bundle_paths import make_splunkhome_path
|
|
sys.path.append(make_splunkhome_path(['etc', 'apps', 'SA-ITOA', 'lib']))
|
|
import itsi_path
|
|
from itsi.backfill.itsi_backfill_requests import BackfillRequestCollection, BackfillRequestModel
|
|
|
|
from ITOA.setup_logging import getLogger
|
|
from ITOA.controller_utils import ITOAError, handle_json_in_splunkd, block_during_migration
|
|
from base_splunkd_rest import BaseSplunkdRest
|
|
|
|
logger = getLogger()
|
|
logger.debug("Initialized backfill services log...")
|
|
|
|
|
|
def handle_path_terms(f):
|
|
def wrapper(self, *args, **kwargs):
|
|
"""
|
|
path must be either
|
|
/services/backfill_services/<owner>
|
|
or
|
|
/services/backfill_services/<owner>/<key id>
|
|
"""
|
|
len_ = len(self.pathParts)
|
|
if len_ > 4 :
|
|
raise ITOAError(status="404", message="Bad argument count.")
|
|
if len_ == 4 :
|
|
self.args.update({ 'id_' : self.pathParts[3] })
|
|
|
|
return f(self, *args, **kwargs)
|
|
return wrapper
|
|
|
|
|
|
class backfill_services(BaseSplunkdRest):
|
|
"""
|
|
Provides splunkd endpoints for backfill operations
|
|
"""
|
|
|
|
def get_interface_adapter(self, session_key, _cached_interface={}):
|
|
"""
|
|
Lazy init method for the interface adapter
|
|
The interface class instance is cached in the mutable _cached_interface default
|
|
arg array and is persisted between calls to this function.
|
|
"""
|
|
if len(_cached_interface) == 0 or session_key not in _cached_interface:
|
|
logger.debug("Caching interface adapter for session key %s", session_key)
|
|
_cached_interface.clear()
|
|
_cached_interface[session_key] = BackfillRequestModel.initialize_interface(session_key)
|
|
|
|
return _cached_interface[session_key]
|
|
|
|
@block_during_migration
|
|
@handle_json_in_splunkd
|
|
@handle_path_terms
|
|
def handle_GET(self):
|
|
interface = self.get_interface_adapter(self.sessionKey)
|
|
|
|
if 'id_' not in self.args :
|
|
filter_data = None
|
|
|
|
if 'filter' in self.args:
|
|
filter_data = json.loads(self.args['filter'])
|
|
|
|
collection = BackfillRequestCollection(interface=interface)
|
|
collection.fetch(filters=filter_data)
|
|
self.response.write(self.render_json([x.data for x in collection]))
|
|
else :
|
|
id_ = self.args['id_']
|
|
try:
|
|
request_model = BackfillRequestModel.fetch_from_key(id_, interface=interface)
|
|
self.response.write(self.render_json(request_model.data))
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
logger.error("Exception thrown when trying to fetch from key %s", id_)
|
|
raise ITOAError(status="404", message="Failed to fetch resource with id {}.".format(id_))
|
|
|
|
def _handlePostPut(self, id_):
|
|
interface = self.get_interface_adapter(self.sessionKey)
|
|
post_data = self.args.get('data') or self.args # postargs get wrapped in 'data' attr
|
|
if id_ :
|
|
request_model = BackfillRequestModel(post_data, key=id_, interface=interface)
|
|
else :
|
|
request_model = BackfillRequestModel(post_data, interface=interface)
|
|
|
|
self.response.write(self.render_json(request_model.save()))
|
|
|
|
@block_during_migration
|
|
@handle_json_in_splunkd
|
|
@handle_path_terms
|
|
def handle_PUT(self):
|
|
if 'id_' not in self.args :
|
|
raise ITOAError(status="404",
|
|
message="PUT request requires the ID_ parameter, "
|
|
"consider POST if you don't wish to pass one")
|
|
|
|
self._handlePostPut(self.args['id_'])
|
|
|
|
@block_during_migration
|
|
@handle_json_in_splunkd
|
|
@handle_path_terms
|
|
def handle_POST(self):
|
|
"""
|
|
parsed args must be the attributes dict for the backfill request
|
|
The following attributes are expected (see itsi_backfill_requests.py for details):
|
|
'status' (set to 'new')
|
|
'search' (obtained from the backfill search endpoint)
|
|
'kpi_id'
|
|
'earliest' (epoch seconds)
|
|
'latest' (epoch seconds)
|
|
"""
|
|
self._handlePostPut(self.args['id_'] if 'id_' in self.args else None)
|
|
|
|
@block_during_migration
|
|
@handle_json_in_splunkd
|
|
@handle_path_terms
|
|
def handle_DELETE(self):
|
|
interface = self.get_interface_adapter(self.sessionKey)
|
|
|
|
if 'id_' not in self.args :
|
|
logger.warning("Batch-deleting all backfill requests!")
|
|
|
|
collection = BackfillRequestCollection(interface=self.get_interface_adapter(self.sessionKey))
|
|
collection.fetch()
|
|
self.response.write(collection.delete())
|
|
|
|
else :
|
|
try:
|
|
request_model = BackfillRequestModel.fetch_from_key(self.args['id_'], interface=interface)
|
|
self.response.write(request_model.delete())
|
|
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
logger.error("Exception thrown when trying to fetch from key %s", self.args['id_'])
|
|
raise ITOAError(status="404", message="Failed to fetch resource with id {}.".format(self.args['id_']))
|