251 lines
9.2 KiB
Python
251 lines
9.2 KiB
Python
#!/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 <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
__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
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
import shutil
|
|
import hcl
|
|
from dotenv import load_dotenv
|
|
|
|
|
|
# [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_proc(proc, data):
|
|
try:
|
|
process = subprocess.Popen([proc, "export"] + data)
|
|
outs = process.wait(timeout=10*60)
|
|
print("[DEBUG]", "Process return code:", outs)
|
|
except subprocess.TimeoutExpired:
|
|
print("[DEBUG]", "Exception occured:", subprocess.TimeoutExpired)
|
|
print("[DEBUG]", "Killing process.")
|
|
process.kill()
|
|
|
|
|
|
# [AA 2021.12.10] Simple copy methd
|
|
def copy(src, dst):
|
|
shutil.copyfile(".\\templates\\" + src, dst)
|
|
|
|
|
|
# [AA, EW 2021.12.13] Check if the path exists and decide between folder or file
|
|
def checkdir(d):
|
|
dflag = False
|
|
|
|
# [AA 2021.12.13] If the path exists and the associated path points to a directory
|
|
if os.path.exists(d) and os.path.isdir(d):
|
|
|
|
# [AA 2021.12.13] If the directory exists, but is empty, delete directory
|
|
if not os.listdir(d):
|
|
|
|
# [AA 2021.12.13] Delete Folder if empty
|
|
print("[DEBUG]", "Found and deleting empty directory:", d)
|
|
os.rmdir(d)
|
|
else:
|
|
print("[DEBUG]", "Found directory:", d)
|
|
dflag = True
|
|
else:
|
|
print("[DEBUG]", "Found file:", d)
|
|
return d, dflag
|
|
|
|
|
|
# [AA 2021.12.13] Fill dictionary
|
|
def readfile(d, f):
|
|
with open(os.path.join(d, f), 'r') 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] Add kay, value to dictionary
|
|
def addentry(key, val, myDict):
|
|
myDict.setdefault(key, [])
|
|
if(val) not in myDict.get(key):
|
|
myDict[key].append(val)
|
|
return myDict
|
|
|
|
|
|
# [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.12.10] Set timestamp once when script is executed
|
|
timestamp = time.strftime("%Y%m%d-%H%M%S")
|
|
|
|
# [AA 2021.11.29] Load enviroment file
|
|
load_dotenv()
|
|
|
|
# [AA 2021.12.10] Set environments/tenants
|
|
Environments = ["EUPROD"]
|
|
# "EUPREPROD",
|
|
# "NAPROD",
|
|
# "NAPREPROD",
|
|
# "CNPROD",
|
|
# "CNPREPROD"]
|
|
|
|
# [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",
|
|
# "dynatrace_service_naming",
|
|
# "dynatrace_host_naming",
|
|
# "dynatrace_processgroup_naming",
|
|
# "dynatrace_slo",
|
|
# "dynatrace_span_entry_point",
|
|
# "dynatrace_span_capture_rule",
|
|
# "dynatrace_span_context_propagation",
|
|
# "dynatrace_resource_attributes",
|
|
# "dynatrace_span_attribute",
|
|
# "dynatrace_mobile_application",
|
|
# "dynatrace_credentials",
|
|
# "dynatrace_browser_monitor",
|
|
# "dynatrace_http_monitor",
|
|
]
|
|
|
|
# [AA 2021.12.13] Set default values
|
|
setdir = '.'
|
|
|
|
# [AA 2021.11.29] Arguments passed
|
|
if(len(sys.argv) == 1):
|
|
|
|
# [AA 2021.12.10] Loop through all four envirionments and two tenants
|
|
for e in Environments:
|
|
|
|
# [AA 2021.12.10] Set environment variables
|
|
env = set_env(e, timestamp, "./configuration/")
|
|
|
|
# [AA 2021.12.10] Run the process synchronously!
|
|
run_proc(".\\bin\\terraform-provider-dynatrace_v1.8.4.exe", Resources)
|
|
|
|
# [AA 2021.12.01] Create main.tf file if it does not exist, otherwise overwrite
|
|
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")
|
|
|
|
# [AA, EW 2021.11.30] Iterate trough each folder in targetfolder, f...file/folder
|
|
for dirname in os.listdir(env['DYNATRACE_TARGET_FOLDER']):
|
|
d, dflag = checkdir(os.path.join(
|
|
env['DYNATRACE_TARGET_FOLDER'], dirname))
|
|
# print('[DEBUG]', 'd', d)
|
|
|
|
# [AA 2021.12.13] If the associated path is a directory
|
|
if dflag:
|
|
|
|
# [AA 2021.12.09] Create empty dictinary to store resource type and resource name
|
|
myDict = {}
|
|
|
|
# [AA 2021.12.01] Loop through directory, eg: management_zones, autotags
|
|
for file in os.listdir(d):
|
|
setskipflag = False
|
|
|
|
# [AA 2021.12.13] Check if there is another subdirectory or a file
|
|
dd, ddflag = checkdir(os.path.join(d, file))
|
|
# print('[DEBUG]', 'ddir', dd, 'ddflag', ddflag)
|
|
|
|
# [AA 2021.12.14] If dd was not deleted and is a "sub"-directory
|
|
if os.path.exists(dd) and ddflag:
|
|
|
|
# [AA 2021.12.13] Set directory
|
|
setdir = dd.replace(os.sep, '/')
|
|
|
|
# [AA 2021.12.13] Loop through that particular directory, where the files are!
|
|
for ffile in os.listdir(dd):
|
|
key, value = readfile(dd, ffile)
|
|
myDict = addentry(key, val, myDict)
|
|
|
|
# [AA 2021.12.14] If dd was not deleted and is not a directory (=a file)
|
|
elif os.path.exists(dd) and ddflag is False:
|
|
|
|
# [AA 2021.12.13] Set directory
|
|
setdir = d.replace(os.sep, '/')
|
|
|
|
# [AA 2021.12.13] There is no subdirectory, it is a file
|
|
# print("[DEBUG]", "Reading", "configDirFile", d)
|
|
key, val = readfile(d, file)
|
|
myDict = addentry(key, val, myDict)
|
|
|
|
# [AA 2021.12.14] The directory was deleted
|
|
elif not os.path.exists(dd) and ddflag is False:
|
|
print("[DEBUG]", "Directory was deleted:", dd)
|
|
setskipflag = True
|
|
|
|
# [AA 2021.12.14] Directory could not be deleted
|
|
elif not os.path.exists(dd) and ddflag is True:
|
|
print("[DEBUG]", "Deletion not successful:", dd)
|
|
setskipflag = True
|
|
|
|
# [AA 2021.12.14] Manual exception will be thrown
|
|
else:
|
|
print("[DEBUG]", "Uncaught Exception Error.")
|
|
setskipflag = True
|
|
|
|
if setskipflag is not True:
|
|
# [AA, EW 2021.11.30] Copy module
|
|
copy("module.tf", setdir + "\\module.tf")
|
|
|
|
# [AA 2021.12.10] Print the amount of resources exported from Dynatrace
|
|
print("[DICTIONARY]", "resource", ", ".join(myDict.keys()),
|
|
"amount", "0" if myDict.get(key) is None else len(myDict.get(key)), "\n")
|
|
|
|
# [AA 2021.12.13] Append the necessary modules to the main.tf file
|
|
writefile(key, setdir)
|
|
# print("[DEBUG]", "Set directory:", setdir)
|
|
|
|
else:
|
|
print("Usage example: ")
|
|
print("python .\exportConfig.py")
|