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.

167 lines
6.1 KiB

import json
import os
import sys
from splunk.persistconn.application import PersistentServerConnectionApplication
from splunk.clilib.bundle_paths import make_splunkhome_path
sys.path.append(make_splunkhome_path(['etc', 'apps', 'DA-ITSI-ContentLibrary', 'lib']))
from itsi_content_constants import CONTENT_TYPE_TO_ITOA_TYPE
from itsi_content_utils import HTTPError
from itsi_content_setup_logging import logger
class EntitlementRuleHandler(PersistentServerConnectionApplication):
def __init__(self, command_line, command_arg):
"""
Basic constructor
@type: string
@param command_line: command line invoked for handler
@type: string
@param command_arg: args for invoked command line for handler
"""
super(PersistentServerConnectionApplication, self).__init__()
def handle(self, args):
"""
Blanket handler for all REST calls on the interface routing the GET/POST/PUT/DELETE requests.
Derived implementation from PersistentServerConnectionApplication.
@type args: json
@param args: a JSON string representing a dictionary of arguments to the REST call.
@rtype: json
@return: a valid REST response
"""
args = json.loads(args)
rest_method = args['method']
if rest_method != 'GET':
raise HTTPError(status="500", message="Unsupported HTTP method {}.".format(rest_method))
rest_path = args['rest_path']
path_parts = rest_path.strip().strip('/').split('/')
if path_parts[2] == 'content_pack_level':
payload = {"entitlement": self.get_content_pack_level_entitlement(path_parts[3])}
elif path_parts[2] == 'object_type_level':
payload = self.get_object_level_entitlement(path_parts[3])
return {'payload': payload, 'status': 200}
def get_content_pack_level_entitlement(self, content_pack_id):
"""
Retrieve complete list of entitlements of a content pack.
We read entitlements for all content types of this content pack from rule.json
and return a list that contains unique values of all these entitlements
:param content_pack_id: the content pack version id
:type content_pack_id: str
:return: content pack level entitlement
:rtype: list
eg: ['standard', 'plus']
"""
logger.info('getting content pack level entitlement for %s', content_pack_id)
object_manifest = self.read_content_pack_file(content_pack_id, 'itsi', 'manifest.json')
rules = self.read_content_pack_file(content_pack_id, 'itsi', 'rule.json')
object_types = [key for key in object_manifest.keys() if key in CONTENT_TYPE_TO_ITOA_TYPE]
entitlements = set()
for entity_type, entitlement_list in rules.get('object_type_entitlement').items():
if entity_type in object_types:
entitlements.update(entitlement_list)
return list(entitlements)
def get_object_level_entitlement(self, content_pack_id):
"""
Retrieve entitlements for all content types of a content pack
We read entitlements for all content types of this content pack from rule.json and return as is
:param content_pack_id: the content pack version id
:type content_pack_id: str
:return: object type level entitlement
:rtype: dict
eg:
{
"correlation_searches": [
"itsi_cp_service_overview"
],
"entity_types": [
"itsi_cp_infra_overview",
"itsi_cp_service_overview"
],
"kpi_base_searches": [
"itsi_cp_service_overview"
],
"services": [
"itsi_cp_service_overview"
],
"notable_event_aggregation_policies": [
"itsi_cp_service_overview"
]
}
"""
logger.info('getting object type level entitlement for %s', content_pack_id)
object_manifest = self.read_content_pack_file(content_pack_id, 'itsi', 'manifest.json')
rules = self.read_content_pack_file(content_pack_id, 'itsi', 'rule.json')
object_types = [key for key in object_manifest.keys() if key in CONTENT_TYPE_TO_ITOA_TYPE]
entitlements = rules['object_type_entitlement']
entitlements = {key: value for key, value in entitlements.items() if key in object_types}
return entitlements
def read_content_pack_file(self, content_pack_id, *path_to_file):
"""
Returns thclient.connect(e file data for the given content pack file.
:param content_pack_id: the content pack id
:type content_pack_id: str
:param path_to_file: list of arguments that specifies path to file
:type path_to_file: list
:return: the file data
:rtype: dict
"""
file_path = EntitlementRuleHandler.make_path_to_content_pack_file(content_pack_id, *path_to_file)
with open(file_path, 'r') as file_object:
contents = file_object.read()
return json.loads(contents)
@staticmethod
def make_path_to_content_pack_file(content_pack_id, *path_to_file):
"""
Returns the file path to the content pack file or directory.
:param content_pack_id: the content pack id
:type content_pack_id: str
:param path_to_file: list of arguments that specifies path to file
:type path_to_file: list
:return: the file path to the content pack file or directory
:rtype: str
"""
try:
file_path = make_splunkhome_path([
'etc',
'apps',
content_pack_id,
*path_to_file
])
if os.path.exists(file_path):
return file_path
else:
return make_splunkhome_path([
'etc',
'apps',
'DA-ITSI-ContentLibrary',
*path_to_file
])
except Exception as e:
logger.exception('Failed to read content pack file for content pack id: %s', content_pack_id)
raise e