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.
Splunk_Deploiement/apps/trackme/bin/trackme_rest_handler_licens...

622 lines
20 KiB

#!/usr/bin/env python
# coding=utf-8
__name__ = "trackme_rest_handler_licensing.py"
__author__ = "TrackMe Limited"
__copyright__ = "Copyright 2022-2026, TrackMe Limited, U.K."
__credits__ = "TrackMe Limited, U.K."
__license__ = "TrackMe Limited, all rights reserved"
__version__ = "0.1.0"
__maintainer__ = "TrackMe Limited, U.K."
__email__ = "support@trackme-solutions.com"
__status__ = "PRODUCTION"
# Built-in libraries
import json
import os
import sys
import time
import uuid
from collections import OrderedDict
# splunk home
splunkhome = os.environ["SPLUNK_HOME"]
# append current directory
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# import libs
import import_declare_test
# set logging
from trackme_libs_logging import setup_logger
logger = setup_logger(
"trackme.rest.licensing_admin", "trackme_rest_api_licensing_admin.log"
)
# Redirect global logging to use the same handler
import logging
logging.getLogger().handlers = logger.handlers
logging.getLogger().setLevel(logger.level)
# import rest handler
import trackme_rest_handler
# import trackme libs
from trackme_libs import trackme_getloglevel
# import trackme licensing libs
from trackme_libs_licensing import (
trackme_return_license_status,
trackme_start_trial,
trackme_return_license_status_offline,
)
# import Splunk libs
import splunklib.client as client
# import cryptolense
from licensing.models import *
from licensing.methods import Key, Helpers
class TrackMeHandlerLicensingAdmin_v2(trackme_rest_handler.RESTHandler):
def __init__(self, command_line, command_arg):
super(TrackMeHandlerLicensingAdmin_v2, self).__init__(
command_line, command_arg, logger
)
def get_resource_group_desc_licensing(self, request_info, **kwargs):
response = {
"resource_group_name": "licensing",
"resource_group_desc": "Endpoints for the purposes of license management (admin operations)",
}
return {"payload": response, "status": 200}
# set the license key
def post_set_license(self, request_info, **kwargs):
describe = False
# Retrieve from data
try:
resp_dict = json.loads(str(request_info.raw_args["payload"]))
except Exception as e:
resp_dict = None
if resp_dict is not None:
try:
describe = resp_dict["describe"]
if describe in ("true", "True"):
describe = True
except Exception as e:
describe = False
else:
describe = False
if not describe:
license_key = resp_dict["license_key"]
# if describe is requested, show the usage
if describe:
response = {
"describe": "This endpoint sets the license key for this deployment, it requires a POST call with the no options:",
"resource_desc": "Get the license status",
"resource_spl_example": '| trackme url="/services/trackme/v2/licensing/admin/license_key" mode="post"',
"options": [
{
"license_key": "The license key to be set",
}
],
}
return {"payload": response, "status": 200}
# Get splunkd port
splunkd_port = request_info.server_rest_port
# Get service
service = client.connect(
owner="nobody",
app="trackme",
port=splunkd_port,
token=request_info.system_authtoken,
timeout=600,
)
# set loglevel
loglevel = trackme_getloglevel(
request_info.system_authtoken, request_info.server_rest_port
)
logger.setLevel(loglevel)
try:
# check the license validity first
response = trackme_return_license_status(license_key)
if int(response.get("license_is_valid")) == 1:
collection_name = "kv_trackme_license_key"
collection = service.kvstore[collection_name]
# Get the current record
# Notes: the record is returned as an array, as we search for a specific record, we expect one record only
try:
kvrecords = collection.data.query()
except Exception as e:
kvrecords = None
if kvrecords:
# Remove any record in the KV
for kvrecord in kvrecords:
key = kvrecord.get("_key")
logger.info(
f'purging KVrecord="{json.dumps(kvrecord, indent=2)}"'
)
collection.data.delete(json.dumps({"_key": key}))
# set
logger.info("attempting to set the license key KVstore record")
collection.data.insert(
json.dumps(
{
"_key": license_key,
"license_string": response.get("license_string"),
"license_type": "subscription",
}
)
)
# log
logger.info(
f'license set key operation terminated, response="{json.dumps(response, indent=2)}"'
)
# return
return {"payload": response, "status": 200}
else:
# return
return {"payload": response, "status": 500}
except Exception as e:
response = {
"action": "failure",
"message": "An exception was encountered while attempting to setup the license key",
"exception": str(e),
}
return {"payload": response, "status": 500}
# Upload license file
def post_upload_license_file(self, request_info, **kwargs):
describe = False
# Retrieve from data
try:
resp_dict = json.loads(str(request_info.raw_args["payload"]))
except Exception as e:
resp_dict = None
if resp_dict is not None:
try:
describe = resp_dict["describe"]
if describe in ("true", "True"):
describe = True
except Exception as e:
describe = False
else:
describe = False
if not describe:
license_file = resp_dict["license_file"]
# if describe is requested, show the usage
if describe:
response = {
"describe": "This endpoint verifies and upload a license file, it requires a POST call with the following options:",
"resource_desc": "Upload license file",
"resource_spl_example": '| trackme url="/services/trackme/v2/licensing/admin/upload_license_file" mode="post"',
"options": [
{
"license_file": "The license file content",
}
],
}
return {"payload": response, "status": 200}
# Get splunkd port
splunkd_port = request_info.server_rest_port
# Get service
service = client.connect(
owner="nobody",
app="trackme",
port=splunkd_port,
token=request_info.system_authtoken,
timeout=600,
)
# set loglevel
loglevel = trackme_getloglevel(
request_info.system_authtoken, request_info.server_rest_port
)
logger.setLevel(loglevel)
try:
# check the license validity first
response = trackme_return_license_status_offline(license_file)
if int(response.get("license_is_valid")) == 1:
collection_name = "kv_trackme_license_key"
collection = service.kvstore[collection_name]
# Get the current record
# Notes: the record is returned as an array, as we search for a specific record, we expect one record only
try:
kvrecords = collection.data.query()
except Exception as e:
kvrecords = None
if kvrecords:
# Remove any record in the KV
for kvrecord in kvrecords:
key = kvrecord.get("_key")
logger.info(
f'purging KVrecord="{json.dumps(kvrecord, indent=2)}"'
)
collection.data.delete(json.dumps({"_key": key}))
# set
logger.info("attempting to set the license key KVstore record")
collection.data.insert(
json.dumps(
{
"license_string": response.get("license_string"),
"license_type": "subscription",
}
)
)
# log
logger.info(
f'license set key operation terminated, response="{json.dumps(response, indent=2)}"'
)
# return
return {"payload": response, "status": 200}
else:
# return
return {"payload": response, "status": 500}
except Exception as e:
response = {
"action": "failure",
"message": "An exception was encountered while attempting to setup the license key",
"exception": str(e),
}
return {"payload": response, "status": 500}
# Start trial license
def post_start_trial(self, request_info, **kwargs):
describe = False
# Retrieve from data
try:
resp_dict = json.loads(str(request_info.raw_args["payload"]))
except Exception as e:
resp_dict = None
if resp_dict is not None:
try:
describe = resp_dict["describe"]
if describe in ("true", "True"):
describe = True
except Exception as e:
describe = False
else:
describe = False
# if describe is requested, show the usage
if describe:
response = {
"describe": "This endpoint starts a trial license period for this deployment, it requires a POST call with no options:",
"resource_desc": "Starts a Trial period",
"resource_spl_example": '| trackme url="/services/trackme/v2/licensing/admin/start_trial" mode="post"',
}
return {"payload": response, "status": 200}
# Get splunkd port
splunkd_port = request_info.server_rest_port
# Get service
service = client.connect(
owner="nobody",
app="trackme",
port=splunkd_port,
token=request_info.system_authtoken,
timeout=600,
)
# set loglevel
loglevel = trackme_getloglevel(
request_info.system_authtoken, request_info.server_rest_port
)
logger.setLevel(loglevel)
try:
# check the license validity first
response = trackme_start_trial(request_info)
logger.info(f'response="{response}"')
if int(response.get("license_is_valid")) == 1:
collection_name = "kv_trackme_license_key"
collection = service.kvstore[collection_name]
# Get the current record
# Notes: the record is returned as an array, as we search for a specific record, we expect one record only
try:
kvrecords = collection.data.query()
except Exception as e:
kvrecords = None
if kvrecords:
# Remove any record in the KV
for kvrecord in kvrecords:
key = kvrecord.get("_key")
logger.info(
f'purging KVrecord="{json.dumps(kvrecord, indent=2)}"'
)
collection.data.delete(json.dumps({"_key": key}))
# set
logger.info("attempting to set the Trial license key KVstore record")
collection.data.insert(
json.dumps(
{
"_key": response.get("trial_key"),
"license_string": response.get("license_string"),
"license_type": "trial",
}
)
)
# log
logger.info(
f'license Trial operation terminated, response="{json.dumps(response, indent=2)}"'
)
# return
if response.get("action") == "success":
return {"payload": response, "status": 200}
else:
return {"payload": response, "status": 500}
else:
# return
return {"payload": response, "status": 500}
except Exception as e:
response = {
"action": "failure",
"message": "An exception was encountered while attempting to generate a Trial license",
"exception": str(e),
}
return {"payload": response, "status": 500}
# Enable developer mode
def post_enable_developer_license(self, request_info, **kwargs):
describe = False
# Retrieve from data
try:
resp_dict = json.loads(str(request_info.raw_args["payload"]))
except Exception as e:
resp_dict = None
if resp_dict is not None:
try:
describe = resp_dict["describe"]
if describe in ("true", "True"):
describe = True
except Exception as e:
describe = False
else:
describe = False
# if describe is requested, show the usage
if describe:
response = {
"describe": "This endpoint enables the developer mode for this deployment, it requires a POST call with no options:",
"resource_desc": "Enable the developer mode license",
"resource_spl_example": '| trackme url="/services/trackme/v2/licensing/admin/enable_developer_license" mode="post"',
}
return {"payload": response, "status": 200}
# Get splunkd port
splunkd_port = request_info.server_rest_port
# Get service
service = client.connect(
owner="nobody",
app="trackme",
port=splunkd_port,
token=request_info.system_authtoken,
timeout=600,
)
# set loglevel
loglevel = trackme_getloglevel(
request_info.system_authtoken, request_info.server_rest_port
)
logger.setLevel(loglevel)
try:
collection_name = "kv_trackme_license_key"
collection = service.kvstore[collection_name]
# Get the current record
# Notes: the record is returned as an array, as we search for a specific record, we expect one record only
try:
kvrecords = collection.data.query()
except Exception as e:
kvrecords = None
if kvrecords:
# Remove any record in the KV
for kvrecord in kvrecords:
key = kvrecord.get("_key")
logger.info(f'purging KVrecord="{json.dumps(kvrecord, indent=2)}"')
collection.data.delete(json.dumps({"_key": key}))
# set
logger.info(
"attempting to set the developer mode license key KVstore record"
)
new_record = {
"license_string": json.dumps(
{
"uuid": str(uuid.uuid4()),
"expires": int(time.time()) + 2592000,
},
indent=2,
),
"license_type": "developer",
}
try:
collection.data.insert(json.dumps(new_record))
response = {
"action": "success",
"license_string": new_record.get("license_string"),
"licence_type": new_record.get("license_type"),
}
except Exception as e:
response = {
"action": "failure",
"license_string": new_record.get("license_string"),
"licence_type": new_record.get("license_type"),
"exception": str(e),
}
# log
logger.info(
f'license developer operation terminated, response="{json.dumps(response, indent=2)}"'
)
# return
if response.get("action") == "success":
return {"payload": response, "status": 200}
else:
return {"payload": response, "status": 500}
except Exception as e:
response = {
"action": "failure",
"message": "An exception was encountered while attempting to enable the developer license",
"exception": str(e),
}
return {"payload": response, "status": 500}
# Reset licensing
def post_reset_license(self, request_info, **kwargs):
describe = False
# Retrieve from data
try:
resp_dict = json.loads(str(request_info.raw_args["payload"]))
except Exception as e:
resp_dict = None
if resp_dict is not None:
try:
describe = resp_dict["describe"]
if describe in ("true", "True"):
describe = True
except Exception as e:
describe = False
else:
describe = False
# if describe is requested, show the usage
if describe:
response = {
"describe": "This endpoint resets the current license registration, it requires a POST call with no options:",
"resource_desc": "Enable the developer mode license",
"resource_spl_example": '| trackme url="/services/trackme/v2/licensing/admin/reset_license" mode="post"',
}
return {"payload": response, "status": 200}
# Get splunkd port
splunkd_port = request_info.server_rest_port
# Get service
service = client.connect(
owner="nobody",
app="trackme",
port=splunkd_port,
token=request_info.system_authtoken,
timeout=600,
)
# set loglevel
loglevel = trackme_getloglevel(
request_info.system_authtoken, request_info.server_rest_port
)
logger.setLevel(loglevel)
try:
collection_name = "kv_trackme_license_key"
collection = service.kvstore[collection_name]
# Get the current record
# Notes: the record is returned as an array, as we search for a specific record, we expect one record only
try:
kvrecords = collection.data.query()
except Exception as e:
kvrecords = None
if kvrecords:
# Remove any record in the KV
for kvrecord in kvrecords:
key = kvrecord.get("_key")
logger.info(f'purging KVrecord="{json.dumps(kvrecord, indent=2)}"')
collection.data.delete(json.dumps({"_key": key}))
# log
logger.info("reset license operation terminated")
return {
"payload": {
"action": "success",
},
"status": 200,
}
except Exception as e:
response = {
"action": "failure",
"message": "An exception was encountered while attempting to reset the current license registration",
"exception": str(e),
}
return {"payload": response, "status": 500}