Pre-release almost finished.
parent
573418528e
commit
3ccc3346f2
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Python: Aktuelle Datei",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
244
exportConfig.py
244
exportConfig.py
|
|
@ -44,7 +44,8 @@ def set_env(env, time, path):
|
||||||
# [AA 2021.12.10] Method to call process synchronously
|
# [AA 2021.12.10] Method to call process synchronously
|
||||||
def run_proc(proc, data):
|
def run_proc(proc, data):
|
||||||
try:
|
try:
|
||||||
process = subprocess.Popen([proc, "export"] + data)
|
inputParam = [proc, "export"] + data
|
||||||
|
process = subprocess.Popen(inputParam)
|
||||||
outs = process.wait(timeout=10*60)
|
outs = process.wait(timeout=10*60)
|
||||||
print("[DEBUG]", "Process return code:", outs)
|
print("[DEBUG]", "Process return code:", outs)
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
|
|
@ -59,29 +60,27 @@ def copy(src, dst):
|
||||||
|
|
||||||
|
|
||||||
# [AA, EW 2021.12.13] Check if the path exists and decide between folder or file
|
# [AA, EW 2021.12.13] Check if the path exists and decide between folder or file
|
||||||
def checkdir(d):
|
def checkdir(path):
|
||||||
dflag = False
|
isFolder = False
|
||||||
|
isDeleted = False
|
||||||
|
|
||||||
# [AA 2021.12.13] If the path exists and the associated path points to a directory
|
# [AA 2021.12.13] If the path exists and the associated path is a folder
|
||||||
if os.path.exists(d) and os.path.isdir(d):
|
if os.path.exists(path) and os.path.isdir(path):
|
||||||
|
isFolder = True
|
||||||
|
|
||||||
# [AA 2021.12.13] If the directory exists, but is empty, delete directory
|
# [AA 2021.12.13] If the folder exists, but is empty, delete folder
|
||||||
if not os.listdir(d):
|
if not os.listdir(path):
|
||||||
|
isDeleted = True
|
||||||
|
|
||||||
# [AA 2021.12.13] Delete Folder if empty
|
# [AA 2021.12.13] Delete Folder if empty
|
||||||
print("[DEBUG]", "Deleting empty directory:", d)
|
os.rmdir(path)
|
||||||
os.rmdir(d)
|
|
||||||
else:
|
return isFolder, isDeleted
|
||||||
print("[DEBUG]", "Found directory:", d)
|
|
||||||
dflag = True
|
|
||||||
else:
|
|
||||||
print("[DEBUG]", "Found file:", d)
|
|
||||||
return d, dflag
|
|
||||||
|
|
||||||
|
|
||||||
# [AA 2021.12.13] Fill dictionary
|
# [AA 2021.12.13] Fill dictionary
|
||||||
def readfile(d, f):
|
def readfile(path):
|
||||||
with open(os.path.join(d, f), 'r') as cfg:
|
with open(path, 'r', encoding='utf8') as cfg:
|
||||||
|
|
||||||
# [AA 2021.12.01] Load the content of the particular resource file in eg: management_zones
|
# [AA 2021.12.01] Load the content of the particular resource file in eg: management_zones
|
||||||
obj = hcl.load(cfg)
|
obj = hcl.load(cfg)
|
||||||
|
|
@ -92,7 +91,7 @@ def readfile(d, f):
|
||||||
return key, val
|
return key, val
|
||||||
|
|
||||||
|
|
||||||
# [AA 2021.12.13] Add kay, value to dictionary
|
# [AA 2021.12.13] Add key, value to dictionary
|
||||||
def addentry(key, val, myDict):
|
def addentry(key, val, myDict):
|
||||||
myDict.setdefault(key, [])
|
myDict.setdefault(key, [])
|
||||||
if(val) not in myDict.get(key):
|
if(val) not in myDict.get(key):
|
||||||
|
|
@ -108,56 +107,56 @@ def writefile(k, d):
|
||||||
|
|
||||||
# [AA 2021.12.10] Set timestamp once when script is executed
|
# [AA 2021.12.10] Set timestamp once when script is executed
|
||||||
timestamp = time.strftime("%Y%m%d-%H%M%S")
|
timestamp = time.strftime("%Y%m%d-%H%M%S")
|
||||||
|
#timestamp = time.strftime("")
|
||||||
|
|
||||||
# [AA 2021.11.29] Load enviroment file
|
# [AA 2021.11.29] Load enviroment file
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
# [AA 2021.12.10] Set environments/tenants
|
# [AA 2021.12.10] Set environments/tenants
|
||||||
Environments = ["EMEA_PROD"
|
Environments = [
|
||||||
# "EMEA_PREPROD",
|
"EMEA_PROD"
|
||||||
# "NA_PROD",
|
# "EMEA_PREPROD",
|
||||||
# "NA_PREPROD",
|
# "NA_PROD",
|
||||||
# "CN_PROD",
|
# "NA_PREPROD",
|
||||||
# "CN_PREPROD"
|
# "CN_PROD",
|
||||||
|
# "CN_PREPROD"
|
||||||
]
|
]
|
||||||
|
|
||||||
# [AA 2021.12.10] Set available resources
|
# [AA 2021.12.10] Set available resources
|
||||||
Resources = [ # "dynatrace_custom_service"
|
Resources = [
|
||||||
|
"dynatrace_custom_service",
|
||||||
"dynatrace_dashboard",
|
"dynatrace_dashboard",
|
||||||
"dynatrace_management_zone",
|
"dynatrace_management_zone",
|
||||||
# "dynatrace_maintenance_window",
|
"dynatrace_maintenance_window",
|
||||||
# "dynatrace_request_attribute",
|
"dynatrace_request_attribute",
|
||||||
"dynatrace_alerting_profile",
|
"dynatrace_alerting_profile",
|
||||||
"dynatrace_notification",
|
"dynatrace_notification",
|
||||||
# "dynatrace_autotag"
|
"dynatrace_autotag"
|
||||||
# "dynatrace_aws_credentials",
|
"dynatrace_aws_credentials",
|
||||||
# "dynatrace_azure_credentials",
|
"dynatrace_azure_credentials",
|
||||||
# "dynatrace_k8s_credentials",
|
"dynatrace_k8s_credentials",
|
||||||
# "dynatrace_service_anomalies",
|
"dynatrace_service_anomalies",
|
||||||
# "dynatrace_application_anomalies",
|
"dynatrace_application_anomalies",
|
||||||
# "dynatrace_host_anomalies",
|
"dynatrace_host_anomalies",
|
||||||
# "dynatrace_database_anomalies",
|
"dynatrace_database_anomalies",
|
||||||
# "dynatrace_custom_anomalies",
|
"dynatrace_custom_anomalies",
|
||||||
# "dynatrace_disk_anomalies",
|
"dynatrace_disk_anomalies",
|
||||||
# "dynatrace_calculated_service_metric",
|
# "dynatrace_calculated_service_metric", #issue -> bug: windows specific due to path length limit
|
||||||
# "dynatrace_service_naming",
|
"dynatrace_service_naming",
|
||||||
# "dynatrace_host_naming",
|
"dynatrace_host_naming",
|
||||||
# "dynatrace_processgroup_naming",
|
"dynatrace_processgroup_naming",
|
||||||
# "dynatrace_slo",
|
# "dynatrace_slo", #issue -> bug: whitespace issue
|
||||||
# "dynatrace_span_entry_point",
|
"dynatrace_span_entry_point",
|
||||||
# "dynatrace_span_capture_rule",
|
"dynatrace_span_capture_rule",
|
||||||
# "dynatrace_span_context_propagation",
|
"dynatrace_span_context_propagation",
|
||||||
# "dynatrace_resource_attributes",
|
"dynatrace_resource_attributes",
|
||||||
# "dynatrace_span_attribute",
|
"dynatrace_span_attribute",
|
||||||
# "dynatrace_mobile_application",
|
"dynatrace_mobile_application",
|
||||||
# "dynatrace_credentials",
|
# "dynatrace_credentials", #issue -> bug: unknown issue? not supported?
|
||||||
# "dynatrace_browser_monitor",
|
"dynatrace_browser_monitor",
|
||||||
# "dynatrace_http_monitor",
|
"dynatrace_http_monitor",
|
||||||
]
|
]
|
||||||
|
|
||||||
# [AA 2021.12.13] Set default values
|
|
||||||
setdir = '.'
|
|
||||||
|
|
||||||
# [AA 2021.11.29] Arguments passed
|
# [AA 2021.11.29] Arguments passed
|
||||||
if(len(sys.argv) == 1):
|
if(len(sys.argv) == 1):
|
||||||
|
|
||||||
|
|
@ -174,78 +173,113 @@ if(len(sys.argv) == 1):
|
||||||
copy("main.tf", ".\\main.tf")
|
copy("main.tf", ".\\main.tf")
|
||||||
|
|
||||||
# [AA, EW 2021.11.30] Copy configuration into each configration folder
|
# [AA, EW 2021.11.30] Copy configuration into each configration folder
|
||||||
copy("configuration.tf",
|
copy("configuration.tf", env['DYNATRACE_TARGET_FOLDER'] + "\\configuration.tf")
|
||||||
env['DYNATRACE_TARGET_FOLDER'] + "\\configuration.tf")
|
|
||||||
|
# [AA 2021.01.14] Set initial values
|
||||||
|
isDeleted = False
|
||||||
|
iisDeleted = False
|
||||||
|
iiisDeleted = False
|
||||||
|
|
||||||
# [AA, EW 2021.11.30] Iterate trough each folder in targetfolder, f could mean file OR folder
|
# [AA, EW 2021.11.30] Iterate trough each folder in targetfolder, f could mean file OR folder
|
||||||
for dirname in os.listdir(env['DYNATRACE_TARGET_FOLDER']):
|
for envdirname in os.listdir(env['DYNATRACE_TARGET_FOLDER']):
|
||||||
d, dflag = checkdir(os.path.join(
|
path = os.path.join(env['DYNATRACE_TARGET_FOLDER'], envdirname)
|
||||||
env['DYNATRACE_TARGET_FOLDER'], dirname))
|
isFolder, isDeleted = checkdir(path)
|
||||||
# print('[DEBUG]', 'd', d)
|
|
||||||
|
|
||||||
# [AA 2021.12.13] If the associated path is a directory
|
# [AA 2021.12.13] If the associated path is a folder, otherwise its the configuration.tf file
|
||||||
if dflag:
|
if isFolder is True and isDeleted is False:
|
||||||
|
|
||||||
# [AA 2021.12.09] Create empty dictinary to store resource type and resource name
|
# [AA 2021.12.09] Create empty dictinary to store resource type and resource name
|
||||||
myDict = {}
|
myDict = {}
|
||||||
|
|
||||||
# [AA 2021.12.01] Loop through directory, eg: management_zones, autotags
|
# [AA 2021.12.01] Loop through folders, eg: management_zones, autotags
|
||||||
for file in os.listdir(d):
|
# [AA 2021.12.13] Check if there is another subdirectory or a file
|
||||||
setskipflag = False
|
for dirname in os.listdir(path):
|
||||||
|
ppath = os.path.join(path, dirname)
|
||||||
|
iisFolder, iisDeleted = checkdir(ppath)
|
||||||
|
|
||||||
# [AA 2021.12.13] Check if there is another subdirectory or a file
|
# [AA 2021.12.14] If there is a "sub"-directory
|
||||||
dd, ddflag = checkdir(os.path.join(d, file))
|
if iisFolder is True and iisDeleted is False:
|
||||||
# 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!
|
# [AA 2021.12.13] Loop through that particular directory, where the files are!
|
||||||
for ffile in os.listdir(dd):
|
for ddirname in os.listdir(ppath):
|
||||||
key, value = readfile(dd, ffile)
|
|
||||||
|
# [AA 2021.12.14] But check if there is another "sub"-"sub"-directory
|
||||||
|
pppath = os.path.join(ppath, ddirname)
|
||||||
|
iiisFolder, iiisDeleted = checkdir(pppath)
|
||||||
|
|
||||||
|
# [AA 2021.12.14] If there is a "sub"-"sub"-directory
|
||||||
|
if iiisFolder is True and iiisDeleted is False:
|
||||||
|
for file in os.listdir(pppath):
|
||||||
|
filepath = os.path.join(pppath, file)
|
||||||
|
|
||||||
|
# [AA 2022.01.13] Try to read file otherwise catch exception
|
||||||
|
try:
|
||||||
|
key, val = readfile(filepath)
|
||||||
|
myDict = addentry(key, val, myDict)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print("File:", filepath)
|
||||||
|
|
||||||
|
# [AA 2021.12.13] Set resource name
|
||||||
|
resource = pppath.replace(os.sep, '/')
|
||||||
|
|
||||||
|
# [AA 2021.12.14] If there is not a "sub"-"sub"-directory
|
||||||
|
elif iiisFolder is False and iiisDeleted is False:
|
||||||
|
filepath = pppath
|
||||||
|
try:
|
||||||
|
key, val = readfile(filepath)
|
||||||
|
myDict = addentry(key, val, myDict)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print("File:", filepath)
|
||||||
|
|
||||||
|
# [AA 2021.12.13] Set resource name
|
||||||
|
resource = ppath.replace(os.sep, '/')
|
||||||
|
|
||||||
|
# [AA 2021.12.14] Manual exception will be thrown
|
||||||
|
elif iiisFolder is True and iiisDeleted is True:
|
||||||
|
print("[DEBUG]", "Deleting and skipping empty folder %s" % (ppath if pppath is None else pppath))
|
||||||
|
|
||||||
|
# [AA 2021.12.14] If there is not a "sub"-directory
|
||||||
|
elif iisFolder is False and iisDeleted is False:
|
||||||
|
filepath = ppath
|
||||||
|
try:
|
||||||
|
key, val = readfile(filepath)
|
||||||
myDict = addentry(key, val, myDict)
|
myDict = addentry(key, val, myDict)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
print("File:", filepath)
|
||||||
|
|
||||||
# [AA 2021.12.14] If dd was not deleted and is not a directory (=a file)
|
# [AA 2021.12.13] Set resource name
|
||||||
elif os.path.exists(dd) and ddflag is False:
|
resource = path.replace(os.sep, '/')
|
||||||
|
|
||||||
# [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
|
# [AA 2021.12.14] Manual exception will be thrown
|
||||||
else:
|
elif iisFolder is True and iisDeleted is True:
|
||||||
print("[DEBUG]", "Uncaught Exception Error.")
|
print("[DEBUG]", "Empty folder deleted %s" % (path if ppath is None else ppath))
|
||||||
setskipflag = True
|
|
||||||
|
|
||||||
if setskipflag is not True:
|
if isDeleted is False and iisDeleted is False and iiisDeleted is False:
|
||||||
# [AA, EW 2021.11.30] Copy module
|
# [AA, EW 2021.11.30] Copy module
|
||||||
copy("module.tf", setdir + "\\module.tf")
|
copy("module.tf", resource + "\\module.tf")
|
||||||
|
|
||||||
# [AA 2021.12.10] Print the amount of resources exported from Dynatrace
|
# [AA 2021.12.10] Print the amount of resources exported from Dynatrace
|
||||||
print("[DICTIONARY]", "resource", ", ".join(myDict.keys()),
|
# [AA 2021.12.14] Multiple keys because they are stored withing the same subfolder
|
||||||
"amount", "0" if myDict.get(key) is None else len(myDict.get(key)), "\n")
|
if len(myDict.keys()) > 1:
|
||||||
|
total = 0
|
||||||
|
print("[DICTIONARY]")
|
||||||
|
for i, (key, value) in enumerate(myDict.items()):
|
||||||
|
print(" ", "resource", key, "amount", "0" if value is None else len(value))
|
||||||
|
total += len(value)
|
||||||
|
print(" ", "total resources", i+1, "total files", total)
|
||||||
|
sys.stdout.write("\n")
|
||||||
|
else:
|
||||||
|
print("[DICTIONARY]", "resource", ", ".join(myDict.keys()), "total files", "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
|
# [AA 2021.12.13] Append the necessary modules to the main.tf file
|
||||||
writefile(key, setdir)
|
writefile(key, resource)
|
||||||
# print("[DEBUG]", "Set directory:", setdir)
|
# print("[DEBUG]", "Set resource:", resource)
|
||||||
|
|
||||||
|
# [AA 2021.12.14] Manual exception will be thrown
|
||||||
|
elif isFolder is True and isDeleted is True:
|
||||||
|
print("[DEBUG]", "Empty folder deleted %s" % path)
|
||||||
|
|
||||||
|
print("[DEBUG]", "Finished.")
|
||||||
else:
|
else:
|
||||||
print("Usage example: ")
|
print("Usage example: ")
|
||||||
print("python .\exportConfig.py")
|
print("python .\exportConfig.py")
|
||||||
|
|
|
||||||
17
main.tf
17
main.tf
|
|
@ -1,7 +1,7 @@
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
dynatrace = {
|
dynatrace = {
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "dynatrace-oss/dynatrace"
|
source = "dynatrace-oss/dynatrace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,15 @@ terraform {
|
||||||
# source = "git::https://github.com/arnauagithub/DynatraceTerraformConfiguration.git?ref=20211130-151123"
|
# source = "git::https://github.com/arnauagithub/DynatraceTerraformConfiguration.git?ref=20211130-151123"
|
||||||
# }
|
# }
|
||||||
|
|
||||||
module "dynatrace_alerting_profile" { source = "./configuration/20211222-154804_EUPROD/alerting_profiles" }
|
module "dynatrace_alerting_profile" { source = "./output/20220117-083219_EMEA_PROD/alerting_profiles" }
|
||||||
module "dynatrace_autotag" { source = "./configuration/20211222-154804_EUPROD/autotags" }
|
module "dynatrace_service_anomalies" { source = "./output/20220117-083219_EMEA_PROD/anomalies" }
|
||||||
module "dynatrace_custom_service" { source = "./configuration/20211222-154804_EUPROD/custom_services" }
|
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" }
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
dynatrace = {
|
dynatrace = {
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "dynatrace-oss/dynatrace"
|
source = "dynatrace-oss/dynatrace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
dynatrace = {
|
dynatrace = {
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "dynatrace-oss/dynatrace"
|
source = "dynatrace-oss/dynatrace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
dynatrace = {
|
dynatrace = {
|
||||||
version = "1.9.0"
|
version = "1.9.1"
|
||||||
source = "dynatrace-oss/dynatrace"
|
source = "dynatrace-oss/dynatrace"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue