dev-create-rest-client #7

Merged
jblu merged 7 commits from dev-create-rest-client into main 2024-07-30 12:58:25 -05:00
8 changed files with 177 additions and 56 deletions

View File

@ -1,10 +1,10 @@
name: Build Inex Executable name: Build
run-name: Deploy to ${{ inputs.deploy_target }} by @${{ gitea.actor }}
on: [push] on: push
jobs: jobs:
linux: build-linux-binary:
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
@ -15,7 +15,23 @@ jobs:
- run: apt-get install unixodbc -y - run: apt-get install unixodbc -y
- run: pip install -r requirements.txt - run: pip install -r requirements.txt
- run: pyinstaller --noconfirm --onefile --console ${{ gitea.workspace }}/inex.py - run: pyinstaller --noconfirm --onefile --console ${{ gitea.workspace }}/inex.py
- uses: actions/upload-artifact@v3 - uses: softprops/action-gh-release@v2
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(gitea.ref, 'refs/tags/')
with: with:
name: Inex files: ${{ gitea.workspace }}/dist/inex
path: ${{ gitea.workspace }}/dist/inex build-windows-binary:
runs-on: windows
permissions:
contents: write # release changes require contents write
steps:
- uses: actions/checkout@v4
- name: Upload Release Asset
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: pip install -r requirements.txt
run: pyinstaller --noconfirm --onefile --console ${{ gitea.workspace }}/inex.py
run: gh release upload <release_tag> <a_file>

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
*config.toml *.toml
*.json *.json
__pycache__/ __pycache__/
*.log *.log
*.token

View File

@ -1,3 +1,27 @@
[fortraPlatform]
selectedPlatform = "dev"
[fortraPlatform.dev]
idp = "https://foundation.foundation-dev.cloudops.fortradev.com/idp/realms/products/protocol/openid-connect/token"
efc_url = "https://efc.efc-dev.cloudops.fortradev.com"
tenant_id = ""
client_id = "eft-event-generator-confidential"
secret = ""
[fortraPlatform.stage]
idp = "https://foundation.foundation-stage.cloudops.fortradev.com/idp/realms/products/protocol/openid-connect/token"
efc_url = "https://efc.efc-stage.cloudops.fortradev.com"
tenant_id = ""
client_id = "eft-event-generator-confidential"
secret = ""
[fortraPlatform.prod]
idp ="https://foundation.foundation-prod.cloudops.fortradev.com/idp/realms/products/protocol/openid-connect/token"
efc_url = "https://efc.efc-prod.cloudops.fortradev.com"
tenant_id = ""
client_id = "eft-event-generator-confidential"
secret = ""
[database] [database]
driver = "ODBC Driver 18 for SQL Server" driver = "ODBC Driver 18 for SQL Server"
server = "192.168.x.x" server = "192.168.x.x"
@ -6,32 +30,33 @@ user = "a"
password = "a" password = "a"
query = """DECLARE @stopTime DATETIME2 query = """DECLARE @stopTime DATETIME2
SET @stopTime = DATEADD(DAY, -30, GETDATE()) SET @stopTime = DATEADD(DAY, -30, GETDATE())
SELECT [ProtocolCommandID] SELECT p.[ProtocolCommandID]
,p.[Time_stamp] ,t.[Time_stamp]
,[RemoteIP] ,p.[RemoteIP]
,[RemotePort] ,p.[RemotePort]
,[LocalIP] ,p.[LocalIP]
,[LocalPort] ,p.[LocalPort]
,[Protocol] ,p.[Protocol]
,[SiteName] ,p.[SiteName]
,[Command] ,p.[Command]
,[CommandParameters] ,p.[CommandParameters]
,[FileName] ,p.[FileName]
,[VirtualFolderName] ,p.[VirtualFolderName]
,[PhysicalFolderName] ,p.[PhysicalFolderName]
,[IsInternal] ,p.[IsInternal]
,[FileSize] ,p.[FileSize]
,[TransferTime] ,p.[TransferTime]
,[BytesTransferred] ,p.[BytesTransferred]
,[ResultID] ,p.[ResultID]
,p.[TransactionID] ,t.[TransactionID]
,[Description] ,p.[Description]
,[Actor] ,p.[Actor]
,t.ParentTransactionID ,t.ParentTransactionID
,t.TransactionObject ,t.TransactionObject
,t.NodeName ,t.NodeName
,t.TransactionGUID ,t.TransactionGUID
FROM [EFTDB].[dbo].[tbl_ProtocolCommands] p Full JOIN tbl_Transactions t ON (p.TransactionID = t.TransactionID) ,a.Protocol user_type
FROM [EFTDB].[dbo].[tbl_Transactions] t Full JOIN tbl_ProtocolCommands p ON (t.TransactionID = p.TransactionID) Full join tbl_Authentications a ON (t.TransactionID = a.TransactionID)
WHERE p.Time_stamp > @stopTime""" WHERE p.Time_stamp > @stopTime"""
[immutables] [immutables]
@ -41,7 +66,10 @@ product_name = "EFT"
product_version ="8.1.0.9" product_version ="8.1.0.9"
[output] [output]
pushToplatform = true
dumpTojson = true
filename ="./data.json" filename ="./data.json"
token = "./.token"
[logging] [logging]
use_log = true use_log = true

46
inex.py
View File

@ -2,27 +2,34 @@ import pyodbc
import os import os
import logging import logging
import datetime import datetime
from tomllib import load import tomllib
from inexLogging import inexLog from inexLogging import inexLog
import inexConnect import inexConnect
from inexDataModel import dataTemplate from inexDataModel import dataTemplate
from inexDataProcessing import processData from inexDataProcessing import processData
import json import json
import decimal import decimal
import requests
import inexEncoder
class Inex: class Inex:
def __init__(self): def __init__(self):
"""Initilize config, calls functions from inex-connect.py and inex-logging.py""" """Initilize config, calls functions from inex-connect.py and inex-logging.py"""
if os.path.exists('./config.toml'):
config_file_path = './config.toml'
with open(config_file_path, 'rb') as c:
self.config = load(c)
# assign libraries # assign libraries
self.db = pyodbc self.db = pyodbc
self.tm = datetime self.tm = datetime
self.il = logging self.il = logging
self.ic = inexConnect self.ic = inexConnect
self.r = requests
self.tl = tomllib
self.os = os
self.j = json
self.e = inexEncoder.Encoder
if self.os.path.exists('./config.toml'):
config_file_path = './config.toml'
with open(config_file_path, 'rb') as c:
self.config = self.tl.load(c)
# set config # set config
self.dbDriver = self.config["database"]["driver"] self.dbDriver = self.config["database"]["driver"]
@ -39,6 +46,18 @@ class Inex:
self.productGUID = self.config["immutables"]["product_guid"] self.productGUID = self.config["immutables"]["product_guid"]
self.productName = self.config["immutables"]["product_name"] self.productName = self.config["immutables"]["product_name"]
self.productVersion = self.config["immutables"]["product_version"] self.productVersion = self.config["immutables"]["product_version"]
self.tokenFilepath = self.config["output"]["token"]
self.selectedPlatform = self.config["fortraPlatform"]["selectedPlatform"]
self.writeJsonfile = self.config["output"]["dumpTojson"]
self.pushToplatform = self.config["output"]["pushToplatform"]
if "dev" in self.selectedPlatform.lower():
self.platformConfig = self.config["fortraPlatform"]["dev"]
if "stag" in self.selectedPlatform.lower():
self.platformConfig = self.config["fortraPlatform"]["stage"]
if "prod" in self.selectedPlatform.lower():
self.platformConfig = self.config["fortraPlatform"]["prod"]
# print(self.platformConfig)
#Setup logging #Setup logging
inexLog(self) inexLog(self)
@ -51,22 +70,15 @@ class Inex:
self.modifiedData = processData(self.data, dataTemplate, prd_instance_id=self.prdInstanceID,\ self.modifiedData = processData(self.data, dataTemplate, prd_instance_id=self.prdInstanceID,\
product_guid=self.productGUID,product_name=self.productName,product_version=self.productVersion) product_guid=self.productGUID,product_name=self.productName,product_version=self.productVersion)
if self.pushToplatform:
inexConnect.fortraEFC.pushPayload(self)
# TODO: move this to its own function # TODO: move this to its own function
if self.useLog: if self.useLog:
self.il.warning(f"Writing to '{self.outputFile}'.") self.il.warning(f"Writing to '{self.outputFile}'.")
if self.writeJsonfile:
with open(self.outputFile, "w") as f: with open(self.outputFile, "w") as f:
json.dump(self.modifiedData, f, indent = 2, cls=Encoder) self.j.dump(self.modifiedData, f, indent = 2, cls=self.e)
# TODO: Move this class to it's own file
class Encoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
return int(o)
if isinstance(o, datetime.datetime):
return str(o)
return super().default(o)
# Run # Run
if __name__== "__main__": if __name__== "__main__":

View File

@ -39,5 +39,35 @@ def databaseQuery(self, cursor, query, args=()):
cur.connection.close() cur.connection.close()
if self.useLog: if self.useLog:
self.il.debug(f"Database connection closed") self.il.debug(f"Database connection closed")
# return (r[0] if r else None) if one else r
return r return r
class fortraEFC:
def getToken(self):
self.tokenData = self.r.post(self.platformConfig["idp"], data={"grant_type":"client_credentials",\
"client_id": self.platformConfig["client_id"],\
"client_secret": self.platformConfig["secret"],})
def writeToken(self):
fortraEFC.getToken(self)
with open(self.tokenFilepath, "w") as f:
self.j.dump(self.tokenData.json(), f, indent = 2)
def readToken(self):
if self.os.path.exists(self.tokenFilepath):
with open(self.tokenFilepath, 'rb') as t:
self.tokenData = self.j.load(t)
# print(self.tokenData["access_token"])
else:
fortraEFC.writeToken(self)
def pushPayload(self):
fortraEFC.readToken(self)
try:
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"]}'},\
json=self.j.dumps(self.modifiedData,indent = 2, cls=self.e))
return pushPayloadResponse.status_code
except self.r.exceptions.HTTPError as errh:
print ("Http Error:",errh)
if "401" in errh:
fortraEFC.writeToken(self)
fortraEFC.pushPayload(self)

View File

@ -28,7 +28,7 @@ def processData(data, template, **kwargs):
user_type=identifyUserType(row.get('user_type')),\ user_type=identifyUserType(row.get('user_type')),\
user_domain=row.get('SiteName'),\ user_domain=row.get('SiteName'),\
user_name=row.get('Actor'),\ user_name=row.get('Actor'),\
utype=row.get('TransactionObject'))) utype=identifyUtype(row.get('TransactionObject'))))
return processedData return processedData
def identifyUserType(obj): def identifyUserType(obj):
@ -39,3 +39,19 @@ def identifyUserType(obj):
return "User" return "User"
else: else:
return None return None
def identifyUtype(obj):
user_logged_on = []
file_deleted = []
file_uploaded = []
file_downloaded = []
if obj in user_logged_on:
return "user_logged_on"
if obj in file_deleted:
return "file_deleted"
if obj in file_uploaded:
return "file_uploaded"
if obj in file_downloaded:
return "file_downloaded"
else:
return None

11
inexEncoder.py Normal file
View File

@ -0,0 +1,11 @@
import json
import decimal
import datetime
class Encoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
return int(o)
if isinstance(o, datetime.datetime):
return int(o.timestamp() * 1000)
return super().default(o)

View File

@ -1,5 +1,12 @@
import datetime
def connectDatabase(driver, server, database, user, password): def connectDatabase(driver, server, database, user, password):
connectionString = f'DRIVER={{{driver}}};SERVER={server};DATABASE={database};UID={user};PWD={password};TrustServerCertificate=yes' connectionString = f'DRIVER={{{driver}}};SERVER={server};DATABASE={database};UID={user};PWD={password};TrustServerCertificate=yes'
print(connectionString) print(connectionString)
a = connectDatabase("ODBC Driver 18 for SQL Server","b","c","d","e") # a = connectDatabase("ODBC Driver 18 for SQL Server","b","c","d","e")
def converttimestamp(t):
print(int(t.timestamp()* 1000))
a = converttimestamp(datetime.datetime(2024, 7, 23, 14, 26, 38, 214000))