feat(doc strings) #18 Add documentation to all functions in code
All checks were successful
Build / build-windows-binary (push) Successful in 33s
Build / build-linux-binary (push) Successful in 1m52s

This commit is contained in:
Jonathan Branan 2024-08-26 14:21:29 -05:00
parent 394c276131
commit 603bc13683
5 changed files with 31 additions and 5 deletions

12
inex.py
View File

@ -13,7 +13,10 @@ import inexSqlquery
class Inex:
def __init__(self):
"""Initilize config, calls functions from inex-connect.py and inex-logging.py"""
"""Initilize config, calls functions from inexConnect.py, inexLogging.py
inexDataModel.py, inexDataProcessing.py, inexEncoder.py and inexSqlquery.py
Main logic of the program. Requires a config.toml in the same directory it's
being run from."""
# assign libraries
self.db = pyodbc
self.il = logging
@ -25,6 +28,7 @@ class Inex:
self.e = inexEncoder.Encoder
self.sq = inexSqlquery
# Check if local config file exists.
if self.os.path.exists('./config.toml'):
config_file_path = './config.toml'
with open(config_file_path, 'rb') as c:
@ -71,18 +75,20 @@ class Inex:
# create the connection to the database
self.cursor = self.ic.inexSql.connectDatabase(self, self.db, self.dbDriver, self.dbServer, self.dbDatabase, self.dbUser, self.dbPassword)
# Query the database
self.data = self.ic.inexSql.databaseQuery(self, self.cursor, self.sq.sqlQuerymodel.queryData(self.queryOverride,self.dbQuery, self.queryDaystopull))
# Modify the data to meet EFC requirements
self.modifiedData = processData(self.data, dataTemplate, prd_ext_tenant_name=self.prdExttenantname,product_name=self.productName,\
prd_ext_tenant_id=self.platformConfig["tenant_id"])
# Push data to EFC. Check for local Auth token -> Authenticate if needed -> push data
if self.pushToplatform:
inexConnect.fortraEFC.__init__(self)
# TODO: move this to its own function
if self.useLog:
self.il.warning(f"Writing to '{self.outputFile}'.")
# Write data to json
if self.writeJsonfile:
with open(self.outputFile, "w") as f:
self.j.dump(self.modifiedData, f, indent = 2, cls=self.e)

View File

@ -20,6 +20,7 @@ class inexSql:
return cursor
def databaseQuery(self, cursor, query, args=()):
"""Use the database connection to send a query."""
if self.useLog:
self.il.debug(f"Query:")
self.il.debug(query)
@ -43,7 +44,10 @@ class inexSql:
return r
class fortraEFC:
"""Class to connect to fortra EFC. It will authenticate and push rest payloads.
Writes a .token file to the same directory script was run in."""
def __init__(self):
"""This is the logic for how authentication is handled"""
# Check if .token file is present
if fortraEFC.readToken(self) == 1:
# Get fresh token. First run.
@ -57,6 +61,8 @@ class fortraEFC:
fortraEFC.pushPayload(self)
def readToken(self):
"""Looks locally for a .token file. Returns a numeral code
for logic in the init method."""
if self.os.path.exists(self.tokenFilepath):
with open(self.tokenFilepath, 'rb') as t:
self.tokenData = self.j.load(t)
@ -66,6 +72,7 @@ class fortraEFC:
return 1
def getToken(self):
"""Gets a token from fortra idp."""
self.tokenData = self.r.post(self.platformConfig["idp"], data={"grant_type":"client_credentials",\
"client_id": self.platformConfig["client_id"],\
"client_secret": self.platformConfig["secret"],})
@ -73,12 +80,14 @@ class fortraEFC:
self.il.debug(f'getToken {self.tokenData["access_token"]}')
def writeToken(self):
"""Writes a token to a local file named '.token'."""
fortraEFC.getToken(self)
with open(self.tokenFilepath, "w") as f:
self.j.dump(self.tokenData, f, indent = 2)
self.il.debug(f'writeToken {self.tokenData["access_token"]}')
def pushPayload(self):
"""Sends data to fortra EFC. Requires a token from the idp."""
self.il.debug(f'pushPayload {self.tokenData["access_token"]}')
url = f'{self.platformConfig["efc_url"]}/api/v1/unity/data/{self.platformConfig["tenant_id"]}/machine_event'
pushPayloadResponse = self.r.post(url, headers={'Authorization': f'Bearer {self.tokenData["access_token"]}'},\

View File

@ -1,4 +1,8 @@
def dataTemplate(transactionType,**kwargs):
"""Created templates for use. This function forms json data into an
appropriate model for EFC. It returnes the appropriate template based
on the transaction type passed into the function. The logic to process
this is at the bottom of the function."""
upload = {
"bytes" : kwargs.get('bytes'),
"dst_endpoint": {

View File

@ -1,7 +1,8 @@
def processData(data, template, **kwargs):
"""Translates data from sql query to the appropriate place in the respective template.
Accepts data, which is the sql query output, the template function, and finally
additional data to insert into the template."""
additional data to insert into the template. Uses other functions to further
process row data."""
processedData = []
transactionLoginid = []
@ -102,6 +103,12 @@ def identifyUserType(obj):
return None
def parseHomefolder(user, virtualfolder):
"""Extract users home folder using the username. Will not work on edge cases
such as when a users home folder does not have the user name. When that occurs
it is impossible to know based on the arm data what the home folder is.
This function is an assumption so it may return the incorrect home folder.
This function finds the user name and takes the path from the left of the folder
as the home folder. There are cases where this may not be accurate."""
if user:
userSplit = f'/{user}/'
if virtualfolder:

View File

@ -1,6 +1,6 @@
class sqlQuerymodel:
def queryData(overRideflag, configQuery, daysTopull):
"""Embedded query data"""
"""Embedded query data. Data is slightly modified to change the amount of days to pull."""
q ="""DECLARE @stopTime DATETIME2
SET @stopTime=DATEADD(DAY, -30, GETDATE())
SELECT p.ProtocolCommandID, t.Time_stamp, p.RemoteIP, p.RemotePort, p.LocalIP, p.LocalPort, p.Protocol, p.SiteName, p.Command, p.FileName, p.PhysicalFolderName, p.VirtualFolderName, p.FileSize, p.TransferTime, p.BytesTransferred, p.Description, p.ResultID, t.TransactionID, p.Actor, t.TransactionObject, t.NodeName, t.TransactionGUID, a.Protocol user_type