import yaml from decouple import config import json import argparse import requests from datetime import datetime from git import Repo import os DASHBOARD_NAME = " - Kubernetes cluster overview" parser = argparse.ArgumentParser(description="Generate and deploy the Kubernetes Overview Dashboard as Code.", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("-C", "--cluster", type=str,required=True, help="Name of the Kubernetes cluster") parser.add_argument('--remove', default=False, action='store_true', help="Remove dashboard for given cluster. If not specified dashboard will be created or updated") parser.add_argument('-E', '--environment', type=str, help="Name of the environment (the same as in environment.yaml file. Used to upload dashboard to specific Dynatrace environment. If not specified all environments in file will be used") parser.add_argument('-O', '--owner', type=str, help="Email address of dashboard owner") args = parser.parse_args() def make_request(url, DTAPIToken,verify, method, jsondata): headers = { 'Content-Type': 'application/json', 'Authorization': 'Api-Token ' + DTAPIToken } try: if method == "get": response = requests.get(url, headers=headers,verify=verify) elif method == "post": response = requests.post(url, headers=headers,verify=verify, data=jsondata) elif method == "put": response = requests.put(url, headers=headers,verify=verify, data=jsondata) elif method == "delete": response = requests.delete(url, headers=headers,verify=verify) 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 get_all_dashboards_withname(DTAPIToken, DTENV,name): DTAPIURL= DTENV + "/api/config/v1/dashboards" r = make_request(DTAPIURL,DTAPIToken,True,"get",None) print(r) entityResponse = r.json() result = [] if("dashboards" in entityResponse): for dashboard in entityResponse["dashboards"]: if(dashboard["name"]).startswith(name): result.append(dashboard) result = sorted(result, key=lambda x : x['name'], reverse=False) return result def remove_dashboards(DTAPIToken, DTENV, dashboards): for dashboard in dashboards: print("Removing dashboard from Dynatrace: "+dashboard["name"]) DTAPIURL = DTENV + "/api/config/v1/dashboards/" + dashboard["id"] print(make_request(DTAPIURL,DTAPIToken,True,"delete",None)) def create_or_update_dashboard(DTAPIToken, DTENV, dashboards, templatename, dashname): with open('./'+templatename) as file: data = file.read() data = data.replace("", args.cluster) tilesjson = json.loads(data) if tilesjson: if any(dashboard["name"] == dashname for dashboard in dashboards): existingdashboard = next((dashboard for dashboard in dashboards if dashboard["name"] == dashname), None) if existingdashboard: print("Found dashboard, Name: "+ existingdashboard["name"]) DTAPIURL = DTENV + "/api/config/v1/dashboards/" + existingdashboard["id"] r = make_request(DTAPIURL,DTAPIToken,True,"get",None) entityResponse = r.json() entityResponse["tiles"] = tilesjson print("Updating dashboard: "+entityResponse["dashboardMetadata"]["name"]) print(make_request(DTAPIURL,DTAPIToken,True,"put",json.dumps(entityResponse))) else: newdashboard = { "dashboardMetadata":{ "name": dashname, "owner": args.owner, "tags": ["Kubernetes"], #"preset": 'true', "shared":'true' }, "tiles":[] } DTAPIURL = DTENV + "/api/config/v1/dashboards" newdashboard["tiles"] = tilesjson print("Creating dashboard: "+newdashboard["dashboardMetadata"]["name"]) print(make_request(DTAPIURL,DTAPIToken,True,"post",json.dumps(newdashboard))) def main(slo_path): print("Generating dashboard...") if args.cluster: FULL_DASHBOARD_NAME = args.cluster + DASHBOARD_NAME print("Getting existing dashboards from Dynatrace") 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("Gather data, hold on a minute") DTTOKEN = config(token.get('env-token-name')) DTURL = url.get('env-url') if args.environment == item: existingdashboards = get_all_dashboards_withname(DTTOKEN, DTURL,FULL_DASHBOARD_NAME) if not args.remove: print("Uploading dashboard to Dynatrace ("+item+")...") create_or_update_dashboard(DTTOKEN, DTURL, existingdashboards, "kubernetes_tiles_template.json", FULL_DASHBOARD_NAME) break else: remove_dashboards(DTTOKEN, DTURL, existingdashboards) else: print("ERROR: No cluster specified") if __name__ == "__main__": main('./shared_configuration/slo_parameter.yaml')