TerraformDynatracePorterOnb.../export.py

203 lines
7.3 KiB
Python

import os
import subprocess
import sys
import time
import shutil
import hcl
from dotenv import load_dotenv
from glob import glob
# [AA 2021.12.10] Method to set environments
def setEnv(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 runProcess(process_name, input_params):
process_names = ["Export", "Terraform init"]
success = False
try:
process = subprocess.Popen(input_params)
process.wait(timeout=60*10) # 10 minutes
success = True
print("[DEBUG]", "Process:", process_name, "Success:", success)
# print("[DEBUG]", "Process return code:", outs)
except subprocess.TimeoutExpired:
print("[DEBUG]", "Exception occured:", subprocess.TimeoutExpired)
print("[DEBUG]", "Killing process:", process_name)
process.kill()
success = False
print("[DEBUG]", "Process:", process_name, "Success:", success)
except:
if process_name in process_names and success == False:
print("[DEBUG]", "Process:", process_name, "Success:", success)
print("[DEBUG]", "Exiting program.")
process.kill()
success = False
sys.exit(1)
else:
print("[FAILED]", input_params)
# [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, EW 2022.01.17] Load all resources and add them to a dictionary
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)
# [AA, EW 2022.01.17] Copy main.tf into the target folder
def copyMainTemplate():
shutil.copyfile(templatesFolder + "main.tf", targetFolder + "main.tf")
# [AA 2022.01.17] Copy module.tf in all folders and subfolders except where main.tf is
def copyModuleTemplate():
dirs = glob(targetFolder + "**/", recursive=True)
for index, dir in enumerate(dirs):
if index != 0:
shutil.copyfile(templatesFolder + "module.tf", dir + "module.tf")
# [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, EW 2022.01.17] Adjust the resource module name
def getModuleTag(str):
return str.replace("./", "").replace("/", "_")
# [AA, EW 2022.01.17] Set the resource names
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 + "\" }")
# [AA, EW 2022.01.17] Start importing
def importStates():
os.chdir(targetFolder)
input_params = ["terraform", "init"]
runProcess("Terraform init",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"]]
runProcess("Import", input_params)
# terraform import module.alerting_profiles.dynatrace_alerting_profiles.CD_ABC 9348098098safs9f8
os.chdir(cwd)
# [AA 2022.01.17] Arguments passed
if(len(sys.argv) == 2):
# [AA 2021.11.29] Load enviroment file
load_dotenv()
# [AA 2022.01.17] 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",
]
# [AA, EW 2022.01.17] Set global variables
global timestamp, templatesFolder, outputFolder, targetFolder, myDict, cwd
# timestamp = time.strftime("%Y%m%d-%H%M%S")
timestamp = "20220120-084944"
cwd = os.getcwd()
outputFolder = "./output/"
targetFolder = outputFolder + timestamp + "_" + sys.argv[1] + "/"
templatesFolder = "./templates/"
myDict = {}
# [AA, EW 2022.01.17] Set env varibales
setEnv(sys.argv[1], timestamp, outputFolder)
# [AA, EW 2022.01.17] Download resource files
# runProcess("Export", [".\\bin\\terraform-provider-dynatrace_v1.9.1.exe", "export"] + Resources)
# [AA, EW 2022.01.17] Create a dictionary to store information of resources
createResourceDict()
# [AA, EW 2022.01.17] Copy main.tf file and add module.tf files
# copyMainTemplate()
# copyModuleTemplate()
# [AA, EW 2022.01.17] Print the module names with their associated module path into the main.tf file
# editMainTF()
# [AA, EW 2022.01.17] Import the states for each module
# importStates()
print("Finished!")
else:
print("Usage example: ")
print("List of available environments: CN_PREPROD, CN_PROD, EMEA_PREPROD, EMEA_PROD, NA_PREPROD, NA_PROD")
print("python .\exportConfig.py EMEA_PROD ")