slo-simply-smarter/project_python/script/Deploy_and_Update_SLO_Simpl...

363 lines
14 KiB
Python

#JLL
import json
import requests
import os
import urllib3
import re
##################################
### Mission Control variables
##################################
Cookie=''
CSRF=''
##################################
### Environment Dynatrace
##################################
Tenant="https://"+str(os.getenv('MyTenant'))
Token=os.getenv('MyToken')
##################################
## API
##################################
APIdashboard='/api/config/v1/dashboards'
APIslo='/api/v2/slo'
##################################
## SLO
##################################
SLO_source={'Optimization - CPU Usage':'d432ca69-7cb0-3dcf-a176-6225a6d5ff4c','Optimization - Disk Usage':'f73c599d-87ba-38e8-98ff-1dae02879969','Optimization - Memory Usage':'ef700817-f0c2-33f8-916d-8dfeb0f1ce3a','Smarter - Application Performance':'eb99760c-52f6-303b-94eb-4a67d5bf3b32','Smarter - Browser Monitor Availability':'2d23383a-8124-3799-916a-548d307ffbcd','Smarter - Database Performance':'91f1aaee-8e54-37cd-9771-cacd0bc977dc','Smarter - Database Success Rate':'c3b96795-e1db-3e55-806b-c4dbba302094','Smarter - Http Monitor Availability':'7dffcc5b-a736-32da-bf7e-a981205fc9fb','Smarter - Service Availability':'a0a88884-5d41-3425-8f02-37436794da80','Smarter - Service Performance':'811465a3-5b0b-3096-9279-02a3d499ba25'}
SLO_target={'Optimization - CPU Usage':'','Optimization - Disk Usage':'','Optimization - Memory Usage':'','Smarter - Application Performance':'','Smarter - Browser Monitor Availability':'','Smarter - Database Performance':'','Smarter - Database Success Rate':'','Smarter - Http Monitor Availability':'','Smarter - Service Availability':'','Smarter - Service Performance':''}
##################################
## Dashboard
##################################
Dashboard_source={'🏠 Dynatrace: simply smarter':'bbbbbbbb-a003-a017-0000-000000000133','✔ SLO Simply Smarter':'bbbbbbbb-a003-a017-0008-000000000133','✔ SLO Resource Optimization':'bbbbbbbb-a003-a017-0009-000000000133','✔ User experience (web applications)':'bbbbbbbb-a003-a017-0002-000000000133','✔ User experience (mobile apps)':'bbbbbbbb-a003-a017-0003-000000000133','✔ Synthetic (browser)':'bbbbbbbb-a003-a017-0004-000000000133','✔ Services':'bbbbbbbb-a003-a017-0001-000000000133','✔ Database services':'bbbbbbbb-a003-a017-0005-000000000133','✔ Synthetic (service)':'bbbbbbbb-a003-a017-0006-000000000133','✔ Infrastructure':'bbbbbbbb-a003-a017-0007-000000000133'}
Dashboard_target={'🏠 Dynatrace: simply smarter':'','✔ SLO Simply Smarter':'','✔ SLO Resource Optimization':'','✔ User experience (web applications)':'','✔ User experience (mobile apps)':'','✔ Synthetic (browser)':'','✔ Services':'','✔ Database services':'','✔ Synthetic (service)':'','✔ Infrastructure':''}
Dashboard_mapping_name={'🏠 Dynatrace: simply smarter':'Dynatrace_simply smarter.json','✔ SLO Simply Smarter':'SLO Simply Smarter.json','✔ SLO Resource Optimization':'SLO Resource Optimization.json','✔ User experience (web applications)':'User experience (web applications).json','✔ User experience (mobile apps)':'User experience (mobile apps).json','✔ Synthetic (browser)':'Synthetic (browser).json','✔ Services':'Services.json','✔ Database services':'Database services.json','✔ Synthetic (service)':'Synthetic (service).json','✔ Infrastructure':'Infrastructure.json'}
##################################
## Others
##################################
deploy=os.getenv('Deploy')
if deploy == None:
deploy = 'ALL'
owner=os.getenv('Owner')
if owner == None:
owner = 'smarter'
owner_old=''
#disable warning
urllib3.disable_warnings()
# variable changed if script is run on Windows or Linux. "\\" for Windows, "/" for Linux
if Cookie == '':
head = {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Api-Token {}'.format(Token)
}
else:
head = {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Api-Token {}'.format(Token),
'X-CSRFToken': CSRF,
'Cookie': Cookie
}
##################################
## Generic Dynatrace API
##################################
# generic function GET to call API with a given uri
def queryDynatraceAPI(uri):
jsonContent = None
#print(head)
response = requests.get(uri,headers=head,verify=False)
#print(response)
# For successful API call, response code will be 200 (OK)
if(response.ok):
if(len(response.text) > 0):
jsonContent = json.loads(response.text)
else:
jsonContent = json.loads(response.text)
print(jsonContent)
errorMessage = ""
if(jsonContent["error"]):
errorMessage = jsonContent["error"]["message"]
print("Dynatrace API returned an error: " + errorMessage)
jsonContent = None
#raise Exception("Error", "Dynatrace API returned an error: " + errorMessage)
return(jsonContent)
#generic function POST to call API with a given uri
def postDynatraceAPI(uri, payload):
jsonContent = None
response = requests.post(uri,headers=head,verify=False, json=payload)
# For successful API call, response code will be 200 (OK)
if(response.ok):
if(len(response.text) > 0):
jsonContent = json.loads(response.text)
jsonContent="success"
else:
jsonContent = json.loads(response.text)
print(jsonContent)
errorMessage = ""
if(jsonContent["error"]):
errorMessage = jsonContent["error"]["message"]
print("Dynatrace API returned an error: " + errorMessage)
jsonContent = None
#raise Exception("Error", "Dynatrace API returned an error: " + errorMessage)
return(jsonContent)
#generic function PUT to call API with a given uri
def putDynatraceAPI(uri, payload):
jsonContent = None
#print(uri,head,payload)
response = requests.put(uri,headers=head,verify=False, json=payload)
# For successful API call, response code will be 200 (OK)
if(response.ok):
jsonContent="success"
else:
jsonContent = json.loads(response.text)
#print(jsonContent)
errorMessage = ""
if (jsonContent["error"]):
errorMessage = jsonContent["error"]["message"]
#print("Dynatrace API returned an error: " + errorMessage)
jsonContent = None
#raise Exception("Error", "Dynatrace API returned an error: " + errorMessage)
return(jsonContent)
##################################
## Get SLO Target
##################################
def getSLO(TENANT, TOKEN):
for slo_filter in ['smarter', 'optimization']:
uri=TENANT+APIslo+'?pageSize=100&sloSelector=text("'+slo_filter+'")&sort=name&timeFrame=CURRENT&demo=false&evaluate=false&enabledSlos=true&showGlobalSlos=true'
#print(uri)
datastore = queryDynatraceAPI(uri)
#print(datastore)
slos = datastore['slo']
for slo in slos :
if slo['name'] in SLO_target:
if SLO_target[slo['name']] == '':
#print(slo['name'])
SLO_target[slo['name']]=slo['id']
return()
def getDashboard(TENANT, TOKEN):
global owner
uri=TENANT+APIdashboard+'?tags=smarter'
#print(uri+'&Api-Token='+Token)
datastore = queryDynatraceAPI(uri)
#print(datastore)
dashboards = datastore['dashboards']
for dashboard in dashboards :
if dashboard['name'] in Dashboard_target:
if Dashboard_target[dashboard['name']] == '':
#print(dashboard['name'])
Dashboard_target[dashboard['name']]=dashboard['id']
owner_old=dashboard['owner']
if owner == '' :
owner == owner_old
return()
def mappSloDashboard(TENANT, TOKEN):
print('\nmapping slo')
uri=TENANT+APIdashboard+'?tags=smarter'
#print(uri)
datastore = queryDynatraceAPI(uri)
#print(datastore)
dashboards = datastore['dashboards']
deploy_dash=False
for dashboard in dashboards :
if dashboard['name'] in ['✔ SLO Simply Smarter', '✔ SLO Resource Optimization'] :
uri=TENANT+APIdashboard+'/'+dashboard['id']
datastore = queryDynatraceAPI(uri)
#print(datastore)
data=json.dumps(datastore)
for i in SLO_source:
if SLO_target[i] != '':
data=re.sub(SLO_source[i], SLO_target[i], data)
print(' mapping slo for ', dashboard['name'],dashboard['id'])
putDynatraceAPI(uri,json.loads(data))
deploy_dash=True
if not deploy_dash:
print(' no dashbaords, import Dynatrace: Simply Smarter or run this script with Deploy=ALL')
return()
def updateSLO(TENANT, TOKEN):
print('\nupdate slo')
for slo in SLO_target:
url='https://raw.githubusercontent.com/dynatrace-ace-services/slo-simply-smarter/main/project_monaco/smarter/slo/'+slo.replace(' ','')+'.json'
req = requests.get(url)
payload=req.json()
payload['name']=slo
payload['id']=SLO_target[slo]
print(' update', slo, SLO_target[slo])
uri=TENANT+APIslo+'/'+SLO_target[slo]
putDynatraceAPI(uri, payload)
return()
def generateSLO(TENANT, TOKEN):
print('\ndeploy slo')
for slo in SLO_target:
if SLO_target[slo] == '':
url='https://raw.githubusercontent.com/dynatrace-ace-services/slo-simply-smarter/main/project_monaco/smarter/slo/'+slo.replace(' ','')+'.json'
req = requests.get(url)
payload=req.json()
payload['name']=slo
print(' deploy', slo, SLO_target[slo])
uri=TENANT+APIslo
result=postDynatraceAPI(uri, payload)
return()
def generateDashboard(TENANT, TOKEN):
print('\ndeploy dashboards')
global owner
if owner == '' :
owner = 'smarter'
for dashboard in Dashboard_target:
if Dashboard_target[dashboard] == '':
url='https://raw.githubusercontent.com/JLLormeau/dynatrace_template_fr/master/'+Dashboard_mapping_name[dashboard]
req = requests.get(url)
payload=req.json()
payload['dashboardMetadata']['owner']=owner
del payload['id']
print(' deploy', dashboard, Dashboard_target[dashboard])
uri=TENANT+APIdashboard
result=postDynatraceAPI(uri, payload)
else:
url='https://raw.githubusercontent.com/JLLormeau/dynatrace_template_fr/master/'+Dashboard_mapping_name[dashboard]
req = requests.get(url)
payload=req.json()
payload['dashboardMetadata']['owner']=owner
payload['id']=Dashboard_target[dashboard]
print(' deploy', dashboard, Dashboard_target[dashboard])
uri=TENANT+APIdashboard+'/'+Dashboard_target[dashboard]
result=putDynatraceAPI(uri, payload)
return()
def mappDashboard(TENANT, TOKEN):
global owner
print('\nupdate dashboards')
for dashboard in Dashboard_target:
uri=TENANT+APIdashboard+'/'+Dashboard_target[dashboard]
datastore = queryDynatraceAPI(uri)
#print(datastore)
datastore['dashboardMetadata']['owner']=owner
data=json.dumps(datastore)
for i in Dashboard_source:
if Dashboard_target[i] != '':
data=re.sub(Dashboard_source[i], Dashboard_target[i], data)
print(' update', dashboard, Dashboard_target[dashboard])
uri=TENANT+APIdashboard+'/'+Dashboard_target[dashboard]
putDynatraceAPI(uri, json.loads(data))
print(' => with owner', owner)
return()
##################################
## Main program
##################################
print("######## SLO Simply Smarter automatic deployment ")
print('\nvariables')
print(' MyTenant', Tenant)
if Tenant == None:
print(' Error Tenant is empty')
exit()
if Token == None:
print(' Error Token is empty')
exit()
if len(Token) > 15 :
print(' MyToken', Token[0:15]+'*****')
else :
print('ERROR : MyToken', Token)
exit()
print(' Deploy', deploy)
if Cookie != '' or CSRF != '' :
print(' Temporary Cookie and CSRFToken from Mission Control')
if len(Cookie) > 30 :
print(' Cookie', Cookie[0:15]+'...'+Cookie[-15:-1])
else:
print(' Cookie', Cookie)
print(' X-CSRFToken', CSRF)
if deploy != 'SLO' and deploy != 'slo' :
print(' Owner', owner)
if Tenant == None :
print('ERROR : MyTenant is empty')
exit()
if Token == None :
print('ERROR : MyToken is empty')
exit()
if Cookie != '' :
if CSRF == '' :
print('ERROR : CSRFToken is empty')
exit()
if CSRF != '' :
if Cookie == '' :
print('ERROR : Cookie is empty')
exit()
#info dashboard
try:
getDashboard(Tenant, Token)
except:
print('Connection ERROR with your tenant "'+Tenant+'" and your token "'+Token[0:15]+'*****"')
exit()
#update dashboards
if deploy != 'SLO' and deploy != 'slo' :
generateDashboard(Tenant, Token)
getDashboard(Tenant, Token)
mappDashboard(Tenant, Token)
#validate slo
getSLO(Tenant, Token)
generateSLO(Tenant, Token)
getSLO(Tenant, Token)
#mapping slo dashboards
mappSloDashboard(Tenant, Token)
#update slo and owner
if deploy != 'SLO' and deploy != 'slo' :
updateSLO(Tenant, Token)
print('\nsimply smarter')
Home=Tenant+"/#dashboard;id="+Dashboard_target['🏠 Dynatrace: simply smarter']
print(' ',Home)
#################################