diff --git a/.vscode/launch.json b/.vscode/launch.json index f636bac..8e33326 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,10 @@ "type": "python", "request": "launch", "program": "${file}", - "console": "integratedTerminal" + "console": "integratedTerminal", + "args": [ + "EMEA_PROD" + ], } ] } \ No newline at end of file diff --git a/export.py b/export.py new file mode 100644 index 0000000..413ab4e --- /dev/null +++ b/export.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python +""" Load Dynatrace Configuration Script. +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Arnautovic Arnel" +__contact__ = "Arnel.Arnautovic@nttdata.com" +__copyright__ = "Copyright 2021, NTT DATA" +__credits__ = ["Ermis Wieger", "René Forstner"] +__date__ = "2021/11/29" +__deprecated__ = False +__license__ = "GPLv3" +__maintainer__ = "developer" +__status__ = "Prototype" +__version__ = "0.0.4" + +# [AA 2021.11.29] Import modules +from logging import exception +from mimetypes import init +import os +from posixpath import split +import subprocess +import sys +import time +import shutil +from tkinter import FALSE, TRUE +import hcl +from dotenv import load_dotenv +from glob import glob + + +# [AA 2021.12.10] Method to set environments +def set_env(env, time, path): + os.environ['DYNATRACE_ENV_URL'] = str(os.getenv(env + "_ENV_URL")) + os.environ['DYNATRACE_API_TOKEN'] = str(os.getenv(env + "_API_TOKEN")) + os.environ['DYNATRACE_TARGET_FOLDER'] = str(path + time + "_" + env) + return os.environ + + +# [AA 2021.12.10] Method to call process synchronously +def run_export(data): + input_params= [".\\bin\\terraform-provider-dynatrace_v1.9.1.exe", "export"]+data + return run_proc(input_params) + +def run_proc(input_params): + success = False + try: + inputParam = input_params#[proc, "export"] + data + process = subprocess.Popen(inputParam) + process.wait(timeout=60*10) # 10 minutes + success = True + # print("[DEBUG]", "Process return code:", outs) + except subprocess.TimeoutExpired: + print("[DEBUG]", "Exception occured:", subprocess.TimeoutExpired) + print("[DEBUG]", "Killing process.") + process.kill() + success = False + return success + +# [AA 2021.12.13] Fill dictionary +def readfile(path): + with open(path, 'r', encoding='utf8') as cfg: + + # [AA 2021.12.01] Load the content of the particular resource file in eg: management_zones + obj = hcl.load(cfg) + + # [AA, EW 2021.12.01] Store resource type and resource name of that file into a dictionary + key = list(obj['resource'].keys())[0] + val = list(obj['resource'][key].keys())[0] + return key, val + +# [AA 2021.12.13] Append correct configuration path +def writefile(k, d): + with open(".\\main.tf", "a") as mf: + mf.writelines("\n" + "module \"" + k + "\" { source = \"" + d + "\" }") + + +# [AA 2021.11.29] Load enviroment file +load_dotenv() + +# [AA 2021.12.10] Set available resources +Resources = [ + "dynatrace_custom_service", + # "dynatrace_dashboard", + # "dynatrace_management_zone", + # "dynatrace_maintenance_window", + # "dynatrace_request_attribute", + "dynatrace_alerting_profile", + # "dynatrace_notification", + # "dynatrace_autotag" + # "dynatrace_aws_credentials", + # "dynatrace_azure_credentials", + # "dynatrace_k8s_credentials", + # "dynatrace_service_anomalies", + # "dynatrace_application_anomalies", + # "dynatrace_host_anomalies", + # "dynatrace_database_anomalies", + # "dynatrace_custom_anomalies", + # "dynatrace_disk_anomalies", + # "dynatrace_calculated_service_metric", #issue -> bug: windows specific due to path length limit + # "dynatrace_service_naming", + # "dynatrace_host_naming", + # "dynatrace_processgroup_naming", + # "dynatrace_slo", # issue -> bug: whitespace issue + # "dynatrace_span_entry_point", + # "dynatrace_span_capture_rule", + # "dynatrace_span_context_propagation", + # "dynatrace_resource_attributes", + # "dynatrace_span_attribute", + # "dynatrace_mobile_application", + # "dynatrace_credentials", #issue -> bug: unknown issue? not supported? + "dynatrace_browser_monitor", + "dynatrace_http_monitor", +] + +def copyMainTemplate(): + shutil.copyfile(templatesFolder + "main.tf", targetFolder + "main.tf") + + +def copyModuleTemplate(): + dirs = glob(targetFolder + "**/", recursive=True) + for index, dir in enumerate(dirs): + if index != 0: + shutil.copyfile(templatesFolder + "module.tf", dir + "module.tf") + +def createResourceDict(): + files = [os.path.normpath(f).replace('\\', '/') for f in glob(targetFolder + "**/**.tf", recursive=True)] + for index, file in enumerate(files): + filedir="./"+("./"+os.path.dirname(file)).replace(targetFolder,"") + splittedFilename=os.path.basename(file).split(".") + + if len(splittedFilename) == 5: + resourceID=splittedFilename[1] + moduleName, resourceName = readfile(file) + + if not filedir in myDict.keys(): + myDict.setdefault(filedir, {}) + + if not moduleName in myDict[filedir].keys(): + myDict[filedir].setdefault(moduleName,[]) + + resourceValue= {"resourceName": resourceName, "resourceID": resourceID} + myDict[filedir][moduleName].append(resourceValue) + + +def getModuleTag(str): + return str.replace("./", "").replace("/", "_") + +def editMainTF(): + with open(targetFolder + "main.tf", "a") as mf: + for index, (filedir, value) in enumerate(myDict.items()): + mf.writelines("\n" + "module \"" + getModuleTag(filedir) + "\" { source = \"" + filedir + "\" }") + +def createState(): + try: + os.chdir(targetFolder) + input_params=["terraform", "init"] + run_proc(input_params) + + for filedir, resourceV in myDict.items(): + for resource, valueArray in resourceV.items(): + for rObject in valueArray: + input_params=["terraform", "import","module."+getModuleTag(filedir)+"."+resource+"."+rObject["resourceName"],rObject["resourceID"]] + run_proc(input_params) + # terraform import module.alerting_profiles.dynatrace_alerting_profiles.CD_ABC 9348098098safs9f8 + except: + print("Exception occured.") + finally: + os.chdir(cwd) + return None + +# [AA 2021.11.29] Arguments passed +if(len(sys.argv) == 2): + + # set init variables + global timestamp, templatesFolder, outputFolder, targetFolder, myDict, cwd + timestamp = time.strftime("%Y%m%d-%H%M%S") + # timestamp = "20220117-143724" + templatesFolder = "./templates/" + outputFolder = "./output/" + targetFolder = outputFolder + timestamp + "_" + sys.argv[1] + "/" + myDict = {} + cwd = os.getcwd() + + # set env varibales + set_env(sys.argv[1], timestamp, outputFolder) + + # download resource files + success = run_export(Resources) + if(success): + print("Export success.") + else: + print("Exiting program.") + sys.exit() ##Exit Code?? + + # copy main.tf file and add module.tf files + createResourceDict() + copyMainTemplate() + copyModuleTemplate() + editMainTF() + + # execute import statements + createState() + +else: + print("Usage example: ") + print("python .\exportConfig.py EMEA_PROD") diff --git a/exportConfig.py b/exportConfig.py index 6bc0950..1f6d24b 100644 --- a/exportConfig.py +++ b/exportConfig.py @@ -125,13 +125,13 @@ Environments = [ # [AA 2021.12.10] Set available resources Resources = [ "dynatrace_custom_service", - "dynatrace_dashboard", - "dynatrace_management_zone", - "dynatrace_maintenance_window", - "dynatrace_request_attribute", - "dynatrace_alerting_profile", - "dynatrace_notification", - "dynatrace_autotag" + # "dynatrace_dashboard", + # "dynatrace_management_zone", + # "dynatrace_maintenance_window", + # "dynatrace_request_attribute", + # "dynatrace_alerting_profile", + # "dynatrace_notification", + # "dynatrace_autotag" "dynatrace_aws_credentials", "dynatrace_azure_credentials", "dynatrace_k8s_credentials", @@ -146,15 +146,15 @@ Resources = [ "dynatrace_host_naming", "dynatrace_processgroup_naming", # "dynatrace_slo", #issue -> bug: whitespace issue - "dynatrace_span_entry_point", - "dynatrace_span_capture_rule", - "dynatrace_span_context_propagation", - "dynatrace_resource_attributes", - "dynatrace_span_attribute", - "dynatrace_mobile_application", + # "dynatrace_span_entry_point", + # "dynatrace_span_capture_rule", + # "dynatrace_span_context_propagation", + # "dynatrace_resource_attributes", + # "dynatrace_span_attribute", + # "dynatrace_mobile_application", # "dynatrace_credentials", #issue -> bug: unknown issue? not supported? - "dynatrace_browser_monitor", - "dynatrace_http_monitor", + # "dynatrace_browser_monitor", + # "dynatrace_http_monitor", ] # [AA 2021.11.29] Arguments passed @@ -173,7 +173,7 @@ if(len(sys.argv) == 1): copy("main.tf", ".\\main.tf") # [AA, EW 2021.11.30] Copy configuration into each configration folder - copy("configuration.tf", env['DYNATRACE_TARGET_FOLDER'] + "\\configuration.tf") + # copy("configuration.tf", env['DYNATRACE_TARGET_FOLDER'] + "\\configuration.tf") # [AA 2021.01.14] Set initial values isDeleted = False diff --git a/main.tf b/main.tf index 3b92832..c9a352b 100644 --- a/main.tf +++ b/main.tf @@ -11,15 +11,8 @@ terraform { # source = "git::https://github.com/arnauagithub/DynatraceTerraformConfiguration.git?ref=20211130-151123" # } -module "dynatrace_alerting_profile" { source = "./output/20220117-083219_EMEA_PROD/alerting_profiles" } -module "dynatrace_service_anomalies" { source = "./output/20220117-083219_EMEA_PROD/anomalies" } -module "dynatrace_mobile_application" { source = "./output/20220117-083219_EMEA_PROD/applications/mobile" } -module "dynatrace_autotag" { source = "./output/20220117-083219_EMEA_PROD/autotags" } -module "dynatrace_k8s_credentials" { source = "./output/20220117-083219_EMEA_PROD/credentials" } -module "dynatrace_custom_service" { source = "./output/20220117-083219_EMEA_PROD/custom_services" } -module "dynatrace_dashboard" { source = "./output/20220117-083219_EMEA_PROD/dashboards" } -module "dynatrace_management_zone" { source = "./output/20220117-083219_EMEA_PROD/management_zones" } -module "dynatrace_service_naming" { source = "./output/20220117-083219_EMEA_PROD/naming/services" } -module "dynatrace_notification" { source = "./output/20220117-083219_EMEA_PROD/notifications" } -module "dynatrace_request_attribute" { source = "./output/20220117-083219_EMEA_PROD/request_attributes" } -module "dynatrace_http_monitor" { source = "./output/20220117-083219_EMEA_PROD/synthetic/http" } \ No newline at end of file + +module "m1" { source = "./output/20220117-132316_EMEA_PROD/anomalies" } +module "m2" { source = "./output/20220117-132316_EMEA_PROD/credentials" } +module "dynatrace_custom_service" { source = "./output/20220117-132316_EMEA_PROD/custom_services" } +module "dynatrace_service_naming" { source = "./output/20220117-132316_EMEA_PROD/naming/services" } \ No newline at end of file diff --git a/templates/configuration.tf b/templates/configuration.tf deleted file mode 100644 index 17cac3b..0000000 --- a/templates/configuration.tf +++ /dev/null @@ -1,9 +0,0 @@ -terraform { - required_providers { - dynatrace = { - version = "1.9.1" - source = "dynatrace-oss/dynatrace" - } - } -} - diff --git a/templates/module.tf b/templates/module.tf index 8877928..17cac3b 100644 --- a/templates/module.tf +++ b/templates/module.tf @@ -6,3 +6,4 @@ terraform { } } } +