coco_apm_reporting_vulnerab.../createReport.py

189 lines
7.5 KiB
Python

from operator import index
from textwrap import indent
from decouple import config
import yaml
import requests
import json
import pandas as pd
import time
from distutils.version import LooseVersion
from dynatraceAPI import Dynatrace
def make_request(url, headers):
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
except requests.exceptions.HTTPError as errh:
return "An Http Error occurred:" + repr(errh)
except requests.exceptions.ConnectionError as errc:
return "An Error Connecting to the API occurred:" + repr(errc)
except requests.exceptions.Timeout as errt:
return "A Timeout Error occurred:" + repr(errt)
except requests.exceptions.RequestException as err:
return "An Unknown Error occurred" + repr(err)
return response
def GatherAllProblems(DTAPIToken, DTENV,friendlyName):
env = DTENV
DTAPIToken = DTAPIToken
dtClient = Dynatrace(env, DTAPIToken)
params = {"pageSize":500
#"fields":'%2BriskAssessment'
}
secProblems = dtClient.returnPageination(f"/api/v2/securityProblems/1340823583484240022?fields=%2BriskAssessment", params, list_item="securityProblems")
df = pd.DataFrame(secProblems.elements)
df.to_csv(friendlyName + '_Allvulnerabilities.csv')
return secProblems
def GatherRemediationItems(DTAPIToken, DTENV,friendlyName):
tags = ["Environment", "Hub", "PaaS", "Cloud", "Platform","Namespace","compass-id","ms-id","app-id","app-name",
"WK","Wirkkette","app","deployment","service","itsm-service","runtime.connected.bmw/managed-app-name",
"controller-revision-hash","name2","statefulset.kubernetes.io/pod-name","stage","MCID"]
env = DTENV
DTAPIToken = DTAPIToken
df = pd.DataFrame()
dtClient = Dynatrace(env, DTAPIToken)
dfEntities = pd.DataFrame()
dfEntities['id']=""
#secProblems = dtClient.returnPageination(f"/api/v2/securityProblems/1340823583484240022?fields=%2BriskAssessment", params, list_item="securityProblems")
problem = dtClient.returnSingle(f"/api/v2/securityProblems/1340823583484240022?fields=%2BriskAssessment")
print(problem)
APIURL = "/api/v2/securityProblems/" + problem['securityProblemId'] + '/remediationItems'
params = {'remediationItemSelector':'vulnerabilityState("VULNERABLE")'}
remItems = dtClient.returnPageination(APIURL, params, list_item="remediationItems")
for Item in remItems.elements:
row={'CVE':problem['cveIds'],
'Title':problem['title'],
'riskLevel':problem['riskAssessment']['riskLevel'],
'riskScore':'[' + str(problem['riskAssessment']['riskScore']) + ']',
'Displayname':Item['name'],
'State':Item['vulnerabilityState'],
'muteState' : Item['muteState']['muted'],
'exposure':Item['assessment']['exposure'],
'dataAssets':Item['assessment']['dataAssets'],
#'firstAffectedDate':time.strftime('%Y-%m-%d', time.localtime(Item['firstAffectedTimestamp']/1000)),
#'firstAffectedTime':time.strftime('%H:%M:%S', time.localtime(Item['firstAffectedTimestamp']/1000))
}
i = 0
for comp in Item['vulnerableComponents']:
row.update({'vulnerableComponent_' + str(i): comp['displayName']})
if (Item['id'] in dfEntities['id']):
entity = dfEntities.loc[dfEntities['id'] == Item['id']]
entity = entity.drop(['id'])
row.update(entity)
else:
APIURL = '/api/v2/entities?entitySelector=entityId("' + Item['id'] + '")&from=now-1h&fields=+tags'
params = {}
enty = dtClient.returnPageination(APIURL,params=params,list_item="entities")
try:
if (len(enty) > 0):
for entity in enty.elements:
tagrow = {'id': entity['entityId']}
for tag in entity['tags']:
if tag['key'] in tags:
try:
tagrow.update({ tag['key']:tag['value']})
row.update({ tag['key']:tag['value']})
except:
tagrow.update({ tag['key']:tag['key']})
row.update({ tag['key']:tag['key']})
dfEntities = dfEntities.append(tagrow, ignore_index=True)
#print("adding host to cache " + str(entity['entityId']) )
#print("df len " + str(len(dfEntities.index)))
except:
print("no entity seen")
df = df.append(row,ignore_index=True)
df.to_csv(friendlyName + '_vulnerabilities.csv')
def GatherNew(DTAPIToken, DTENV,friendlyName):
secProblems = GatherAllProblems(DTAPIToken, DTENV,friendlyName)
GatherRemediationItems(DTAPIToken, DTENV,friendlyName, secProblems)
return
def GatherReportingInfo(DTAPIToken, DTENV,friendlyName):
env = DTENV
DTAPIToken = DTAPIToken
DTAPIURL= env + "/api/v2/securityProblems/1340823583484240022/remediationItems"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Api-Token ' + DTAPIToken
}
r = make_request(DTAPIURL,headers)
df = pd.DataFrame()
mgmt = pd.DataFrame()
for Item in r.json()['remediationItems']:
row={'Name':Item['name'],'State':Item['vulnerabilityState'],'exposure':Item['assessment']['exposure'],'dataAssets':Item['assessment']['dataAssets'],'firstAffectedTimestamp':time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(Item['firstAffectedTimestamp']/1000))}
if 'resolvedTimestamp' in Item.keys():
row.update({'Resolved':time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(Item['resolvedTimestamp']/1000))})
DTAPIURL= env + "/api/v2/entities/" + Item['id']
r = make_request(DTAPIURL,headers)
for tag in r.json()['tags']:
try:
row.update({ tag['key']:tag['value']})
except:
row.update({ tag['key']:tag['key']})
for vulComp in Item['vulnerableComponents']:
min_version='9.0.0-0'
for PGI in vulComp['affectedEntities']:
DTAPIURL= env + "/api/v2/entities/" + PGI
r = make_request(DTAPIURL,headers)
if 'installerVersion' in r.json()['properties']:
current_version = r.json()['properties']['installerVersion']
print(current_version)
if LooseVersion(current_version) < LooseVersion(min_version):
min_version=current_version
row.update({'vulnerableComponent':vulComp['fileName'],'oldestOneAgent':min_version})
df = df.append(row,ignore_index=True)
df.to_csv(friendlyName + 'log4j_vulnerability.csv')
with open('./environment.yaml') as file:
doc = yaml.safe_load(file)
for item, doc in doc.items():
token = dict(doc[2])
url = dict(doc[1])
print("Crawling through: " + item)
print("Check if token exists in environment...")
if(config(token.get('env-token-name')) != ""):
print("Gather data, hold on a minute")
DTTOKEN = config(token.get('env-token-name'))
DTURL = url.get('env-url')
GatherRemediationItems(DTTOKEN,DTURL,item)
else:
print("token not found, skipping " + item)