more comments, better logging

This commit is contained in:
m0duspwnens
2024-04-18 10:26:10 -04:00
parent 4caa6a10b5
commit 506bbd314d
2 changed files with 60 additions and 40 deletions

View File

@@ -1,17 +1,19 @@
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
# -*- coding: utf-8 -*-
import logging
from time import sleep
import os
import salt.client
import re
from ast import literal_eval
import salt.client
log = logging.getLogger(__name__)
local = salt.client.LocalClient()
def start(fpa, interval=10):
log.info("##### PILLARWATCH STARTED #####")
log.info("pillarWatch engine: started")
# try to open the file that stores the previous runs data
# if the file doesn't exist, create a blank one
@@ -19,77 +21,95 @@ def start(fpa, interval=10):
# maybe change this location
dataFile = open("/opt/so/state/pillarWatch.txt", "r+")
except FileNotFoundError:
log.info("No previous pillarWatch data saved")
log.warn("pillarWatch engine: No previous pillarWatch data saved")
dataFile = open("/opt/so/state/pillarWatch.txt", "w+")
df = dataFile.read()
log.info("df: %s" % str(df))
log.info("FPA: %s" % str(fpa))
for i in fpa:
log.trace("files: %s" % i['files'])
log.trace("pillar: %s" % i['pillar'])
log.trace("action: %s" % i['actions'])
log.trace("pillarWatch engine: files: %s" % i['files'])
log.trace("pillarWatch engine: pillar: %s" % i['pillar'])
log.trace("pillarWatch engine: actions: %s" % i['actions'])
pillarFiles = i['files']
pillar = i['pillar']
actions = i['actions']
# these are the keys that we are going to look for as we traverse the pillarFiles
patterns = pillar.split(".")
log.trace("pillar: %s" % pillar)
log.trace("patterns: %s" % patterns)
log.trace("patterns length: %i" % len(patterns))
# this var is used to track how many times the pattern has been found in the pillar file so that we can access the proper index later
patternFound = 0
for pillarFile in pillarFiles:
with open(pillarFile, "r") as file:
log.info("checking file: %s" % pillarFile)
log.info("pillarWatch engine: checking file: %s" % pillarFile)
for line in file:
log.trace("line: %s" % line)
log.trace("pillarWatch engine: inspecting line: %s in file: %s" % (line, file))
log.trace("pillarWatch engine: looking for: %s" % patterns[patternFound])
# since we are looping line by line through a pillar file, the next line will check if each line matches the progression of keys through the pillar
# ex. if we are looking for the value of global.pipeline, then this will loop through the pillar file until 'global' is found, then it will look
# for pipeline. once pipeline is found, it will record the value
if re.search(patterns[patternFound], line):
log.trace("PILLARWATCH FOUND: %s" % patterns[patternFound])
if re.search(patterns[patternFound] + ':', line):
# strip the newline because it makes the logs u-g-l-y
log.info("pillarWatch engine: found: %s" % line.strip('\n'))
patternFound += 1
# we have found the final key in the pillar that we are looking for, get the previous value then the current value
if patternFound == len(patterns):
# at this point, df is equal to the contents of the pillarWatch file that is used to tract the previous values of the pillars
previousPillarValue = 'PREVIOUSPILLARVALUENOTSAVEDINDATAFILE'
# check the contents of the dataFile that stores the previousPillarValue(s).
# find if the pillar we are checking for changes has previously been saved. if so, grab it's prior value
for l in df.splitlines():
if pillar in l:
previousPillarValue = l.split(":")[1].strip()
log.info("%s previousPillarValue: %s" % (pillar, str(previousPillarValue)))
previousPillarValue = str(l.split(":")[1].strip())
log.info("pillarWatch engine: %s previousPillarValue: %s" % (pillar, previousPillarValue))
currentPillarValue = str(line.split(":")[1]).strip()
log.info("%s currentPillarValue: %s" % (pillar,currentPillarValue))
log.info("pillarWatch engine: %s currentPillarValue: %s" % (pillar, currentPillarValue))
# if the pillar we are checking for changes has been defined in the dataFile,
# replace the previousPillarValue with the currentPillarValue. if it isn't in there, append it.
if pillar in df:
df = re.sub(r"\b{}\b.*".format(pillar), pillar + ': ' + currentPillarValue, df)
else:
df += pillar + ': ' + currentPillarValue + '\n'
log.info("df: %s" % df)
log.trace("pillarWatch engine: df: %s" % df)
# we have found the pillar so we dont need to loop throught the file anymore
break
# if the pillar value changed, then we find what actions we should take
log.info("pillarWatch engine: checking if currentPillarValue != previousPillarValue")
log.info("pillarWatch engine: %s currentPillarValue: %s" % (pillar, currentPillarValue))
log.info("pillarWatch engine: %s previousPillarValue: %s" % (pillar, previousPillarValue))
if currentPillarValue != previousPillarValue:
log.info("cPV != pPV: %s != %s" % (currentPillarValue,previousPillarValue))
log.info("pillarWatch engine: currentPillarValue != previousPillarValue: %s != %s" % (currentPillarValue, previousPillarValue))
# check if the previous pillar value is defined in the pillar from -> to actions
if previousPillarValue in actions['from']:
ACTIONS=actions['from'][previousPillarValue]['to'][currentPillarValue]
# check if the new / current pillar value is defined under to
if currentPillarValue in actions['from'][previousPillarValue]['to']:
ACTIONS=actions['from'][previousPillarValue]['to'][currentPillarValue]
# if the new / current pillar value isn't defined under to, is there a wildcard defined
elif '*' in actions['from'][previousPillarValue]['to']:
ACTIONS=actions['from'][previousPillarValue]['to']['*']
# no action was defined for us to take when we see the pillar change
else:
ACTIONS='NO DEFINED ACTION FOR US TO TAKE'
# if the previous pillar wasn't defined in the actions from, is there a wildcard defined for the pillar that we are changing from
elif '*' in actions['from']:
# is the new pillar value defined for the wildcard match
if currentPillarValue in actions['from']['*']['to']:
ACTIONS=actions['from']['*']['to'][currentPillarValue]
# if the new pillar doesn't have an action, was a wildcard defined
elif '*' in actions['from']['*']['to']:
# need more logic here for to and from
ACTIONS=actions['from']['*']['to']['*']
ACTIONS=actions['from']['*']['to']['*']
else:
ACTIONS='NO DEFINED ACTION FOR US TO TAKE'
# a match for the previous pillar wasn't defined in the action in either the form of a direct match or wildcard
else:
ACTIONS='FROM TO NOT DEFINED'
#for f in actions:
log.info("actions: %s" % actions['from'])
log.info("ACTIONS: %s" % ACTIONS)
ACTIONS='NO DEFINED ACTION FOR US TO TAKE'
log.info("pillarWatch engine: actions: %s" % actions['from'])
log.info("pillarWatch engine: ACTIONS: %s" % ACTIONS)
for action in ACTIONS:
log.info(action)
log.info("pillarWatch engine: action: %s" % action)
for saltModule, args in action.items():
log.info(saltModule)
log.info(args)
# args=list(action.values())[0]
# log.info(args)
whatHappened = __salt__[saltModule](**args)
log.info("whatHappened: %s" % whatHappened)
log.info("pillarWatch engine: saltModule: %s" % saltModule)
log.info("pillarWatch engine: args: %s" % args)
actionReturn = __salt__[saltModule](**args)
log.info("pillarWatch engine: actionReturn: %s" % actionReturn)
dataFile.seek(0)
dataFile.write(df)

View File

@@ -12,14 +12,14 @@ engines:
pillar: global.pipeline
actions:
from:
REDIS:
'*':
to:
KAFKA:
- cmd.run:
cmd: /usr/sbin/so-yaml.py replace /opt/so/saltstack/local/pillar/kafka/soc_kafka.sls kafka.enabled True
KAFKA:
to:
REDIS:
'*':
- cmd.run:
cmd: /usr/sbin/so-yaml.py replace /opt/so/saltstack/local/pillar/kafka/soc_kafka.sls kafka.enabled False
- files: