Compare commits

..

4 Commits

Author SHA1 Message Date
2999b4b0ce Removed comments 2024-06-22 17:14:30 +02:00
e2594bc66d Eliminar README.md 2024-06-22 17:09:17 +02:00
38e208642a Script working 2024-06-22 17:08:47 +02:00
8ff792cffc changed gitignore 2024-06-19 00:12:56 +02:00
13 changed files with 64 additions and 323 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,3 @@
.venv
detelete_old_clients_ds/output/
detelete_old_clients_ds/detelete_old_clients_ds-*.tar.gz
delete_old_clients_ds/output/
delete_old_clients_ds/delete_old_clients_ds-*.tar.gz

View File

@@ -1,5 +0,0 @@
# Splunk Add-on to delete old clients from Deployment Server
Interesting Commands:
- Build Add-on: ucc-gen build --ta-version="Tag version"
- Package Add-on:ucc-gen package -o . --path "path to output/app.manifest"

View File

@@ -1 +0,0 @@
# detelete_old_clients_ds

View File

@@ -1,119 +0,0 @@
{
"pages": {
"configuration": {
"tabs": [
{
"name": "account",
"table": {
"actions": [
"edit",
"delete",
"clone"
],
"header": [
{
"label": "Name",
"field": "name"
}
]
},
"entity": [
{
"type": "text",
"label": "Name",
"validators": [
{
"type": "regex",
"errorMsg": "Account Name must begin with a letter and consist exclusively of alphanumeric characters and underscores.",
"pattern": "^[a-zA-Z]\\w*$"
},
{
"type": "string",
"errorMsg": "Length of input name should be between 1 and 100",
"minLength": 1,
"maxLength": 100
}
],
"field": "name",
"help": "A unique name for the account.",
"required": true
},
{
"type": "text",
"label": "Username",
"field": "username",
"help": "Deployment server username",
"required": true
},
{
"type": "text",
"label": "Password",
"field": "password",
"help": "Password",
"required": true,
"encrypted": true
}
],
"title": "Accounts"
},
{
"type": "loggingTab"
}
],
"title": "Configuration",
"description": "Set up your add-on"
},
"inputs": {
"title": "Inputs",
"description": "Manage your data inputs",
"services": [
{
"name": "example_input_one",
"title": "Example Input",
"entity": [
{
"type": "text",
"label": "Deployment Server URL",
"field": "url",
"help": "URL of the DS instance",
"required": true
},
{
"type": "interval",
"field": "interval",
"label": "Interval",
"help": "Time interval of the data input, in seconds .",
"required": true
}
]
}
],
"table": {
"actions": [
"edit",
"enable",
"delete",
"search",
"clone"
],
"header": [],
"moreInfo": []
}
},
"dashboard": {
"panels": [
{
"name": "default"
}
]
}
},
"meta": {
"name": "delete_old_clients_ds",
"restRoot": "delete_old_clients_ds",
"version": "0.0.0",
"displayName": "DS Add-on Delete old clients",
"schemaVersion": "0.0.7",
"_uccVersion": "5.46.0"
}
}

View File

@@ -1,57 +0,0 @@
{
"schemaVersion": "2.0.0",
"info": {
"title": "DS Add-on Delete old clients",
"id": {
"group": null,
"name": "delete_old_clients_ds",
"version": "0.0.1"
},
"author": [
{
"name": "",
"email": null,
"company": null
}
],
"releaseDate": null,
"description": "DS Add-on Delete old clients",
"classification": {
"intendedAudience": "IT Professionals",
"categories": [
"Security, Fraud & Compliance"
],
"developmentStatus": "Production/Stable"
},
"commonInformationModels": null,
"license": {
"name": null,
"text": "LICENSE.txt",
"uri": null
},
"privacyPolicy": {
"name": null,
"text": null,
"uri": null
},
"releaseNotes": {
"name": "README",
"text": "README.txt",
"uri": ""
}
},
"dependencies": null,
"tasks": null,
"inputGroups": null,
"incompatibleApps": null,
"platformRequirements": null,
"supportedDeployments": [
"_standalone",
"_distributed",
"_search_head_clustering"
],
"targetWorkloads": [
"_search_heads",
"_indexers"
]
}

View File

@@ -1,39 +0,0 @@
import import_declare_test
import sys
from splunklib import modularinput as smi
from delete_old_clients_ds_helper import stream_events, validate_input
class DELETE_OLD_CLIENTS_DS(smi.Script):
def __init__(self):
super(DELETE_OLD_CLIENTS_DS, self).__init__()
def get_scheme(self):
scheme = smi.Scheme('delete_old_clients_ds')
scheme.description = 'demo_input input'
scheme.use_external_validation = True
scheme.streaming_mode_xml = True
scheme.use_single_instance = False
scheme.add_argument(
smi.Argument(
'name',
title='Name',
description='Name',
required_on_create=True
)
)
return scheme
def validate_input(self, definition: smi.ValidationDefinition):
return validate_input(definition)
def stream_events(self, inputs: smi.InputDefinition, ew: smi.EventWriter):
return stream_events(inputs, ew)
if __name__ == '__main__':
exit_code = DELETE_OLD_CLIENTS_DS().run(sys.argv)
sys.exit(exit_code)

View File

@@ -1,89 +0,0 @@
import json
import logging
import import_declare_test
from solnlib import conf_manager, log
from splunklib import modularinput as smi
ADDON_NAME = "detelete_old_clients_ds"
def logger_for_input(input_name: str) -> logging.Logger:
return log.Logs().get_logger(f"{ADDON_NAME.lower()}_{input_name}")
def get_account_api_key(session_key: str, account_name: str):
cfm = conf_manager.ConfManager(
session_key,
ADDON_NAME,
realm=f"__REST_CREDENTIAL__#{ADDON_NAME}#configs/conf-detelete_old_clients_ds_account",
)
account_conf_file = cfm.get_conf("detelete_old_clients_ds_account")
return account_conf_file.get(account_name).get("api_key")
def get_data_from_api(logger: logging.Logger, api_key: str):
logger.info("Getting data from an external API")
dummy_data = [
{
"line1": "hello",
},
{
"line2": "world",
},
]
return dummy_data
def validate_input(definition: smi.ValidationDefinition):
return
def stream_events(inputs: smi.InputDefinition, event_writer: smi.EventWriter):
# inputs.inputs is a Python dictionary object like:
# {
# "delete_old_clients_ds://<input_name>": {
# "account": "<account_name>",
# "disabled": "0",
# "host": "$decideOnStartup",
# "index": "<index_name>",
# "interval": "<interval_value>",
# "python.version": "python3",
# },
# }
for input_name, input_item in inputs.inputs.items():
normalized_input_name = input_name.split("/")[-1]
logger = logger_for_input(normalized_input_name)
try:
session_key = inputs.metadata["session_key"]
log_level = conf_manager.get_log_level(
logger=logger,
session_key=session_key,
app_name=ADDON_NAME,
conf_name=f"{ADDON_NAME}_settings",
)
logger.setLevel(log_level)
log.modular_input_start(logger, normalized_input_name)
api_key = get_account_api_key(session_key, input_item.get("account"))
data = get_data_from_api(logger, api_key)
sourcetype = "dummy-data"
for line in data:
event_writer.write_event(
smi.Event(
data=json.dumps(line, ensure_ascii=False, default=str),
index=input_item.get("index"),
sourcetype=sourcetype,
)
)
log.events_ingested(
logger,
normalized_input_name,
sourcetype,
len(data),
input_item.get("index"),
account=input_item.get("account"),
)
log.modular_input_end(logger, normalized_input_name)
except Exception as e:
log.log_exception(logger, e, "my custom error type", msg_before="Exception raised while ingesting data for demo_input: ")

View File

@@ -1,8 +0,0 @@
import requests
class deleteClientDS():
def __init__(self):
deployment_server = os.getenv('SPLUNK_DS')
splunk_username = os.getenv('SPLUNK_DS_USER')
splunk_password = os.getenv('SPLUNK_DS_PASS')

View File

@@ -1,3 +0,0 @@
splunktaucclib
splunk-sdk
solnlib

61
removeOldClientsDS.py Normal file
View File

@@ -0,0 +1,61 @@
import time
import splunklib.client as client
from splunklib.results import JSONResultsReader
from splunklib.binding import HTTPError
def connectSplunk():
HOST = "10.218.7.194"
PORT = 8089
USERNAME = "" # Configurar como variable de entorno
PASSWORD = "" # Configurar como variable de entorno
try:
service = client.connect(host=HOST, port=PORT, username=USERNAME, password=PASSWORD)
print(service.token)
return service
except Exception as e:
print(f'An error occurred while connecting to Splunk: {e}')
return None
def searchOldClient(service):
search = ('| rest splunk_server=local /services/deployment/server/clients '
'| eval last_seen = now() - lastPhoneHomeTime '
'| where last_seen > 86400 '
'| rename clientName as guid '
'| fields guid')
try:
service.parse(search, parse_only=True)
except HTTPError as e:
print(f"query '{search}' is invalid:\n\t{str(e)}")
return
job = service.jobs.create(search)
while not job.is_done():
time.sleep(2)
result_stream = job.results(output_mode='json')
results_reader = JSONResultsReader(result_stream)
guids = list()
for result in results_reader:
if isinstance(result, dict) and 'guid' in result:
guids.append(result['guid'])
return guids
def remove_client(service, guid):
print(f'Removing: {guid}')
endpoint = f'/services/deployment/server/clients/{guid}'
try:
response = service.delete(endpoint)
print(f'Status: {response.status}')
except HTTPError as e:
print(f'Failed to remove client {guid}: {str(e)}')
if __name__ == "__main__":
service = connectSplunk()
if service:
old_clients = searchOldClient(service)
for guid in old_clients:
remove_client(service, guid)

View File

@@ -27,6 +27,7 @@ def find_old_clients():
'| rename clientName as guid '
'| fields guid')
data = { 'search': search }
print(data)
header = {
'Content-Type: application/json'
}