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)