diff --git a/main.py b/main.py index e69de29..2c8a11c 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +""" +Input: This script takes a csv file containing the campaign name and uuid as attributes as input as following: + +campaigns.csv + +name | uuid +-------------------------------------------------------- +NIRA_Denmark_2023 | c5c454c1-6470-407c-9b22-b9af4560d65c +NIRA_France_2023 | 9d4af2c8-ca3f-4c4e-99c4-64081581d7c4 +. +. +. +-------------------------------------------------------- + +Output: This script generates a terraform file for a services' request attribute, which is based on a rendered template. + +The input .csv file shall be stored within the default input directory. + +Usage: main.py +""" +import argparse +import configparser +import csv +import jinja2 +import logging +import pathlib + + +FORMAT = '%(asctime)s %(message)s' +logging.basicConfig(format=FORMAT) +logger = logging.getLogger('main') +logger.setLevel(logging.INFO) + +config = configparser.ConfigParser() +config.read("config.ini") + +DEFAULT_INPUT_PATH = pathlib.Path(config['PATHS']['Input']).absolute() +DEFAULT_OUTPUT_PATH = pathlib.Path(config['PATHS']['Output']).absolute() +DEFAULT_TEMPLATES_PATH = pathlib.Path(config['PATHS']['Templates']).absolute() + +parser = argparse.ArgumentParser(description="Name of the Services' Chain, e.g. Connected_Friction") +parser.add_argument("--name", "-n", type=str, metavar='', required=True, help="Example: Connected_Friction") +args = parser.parse_args() + +env = jinja2.Environment(loader=jinja2.FileSystemLoader(DEFAULT_TEMPLATES_PATH)) +template = env.get_template("service.request_attribute.tf") + +def checkDirectories(DEFAULT_INPUT_PATH, DEFAULT_OUTPUT_PATH, DEFAULT_TEMPLATES_PATH): + for dir in [DEFAULT_INPUT_PATH, DEFAULT_OUTPUT_PATH, DEFAULT_TEMPLATES_PATH]: + + try: + pathlib.Path.mkdir(dir) + logger.info("Directory created: %s", dir) + except FileExistsError: + logger.info("Directory already exists: %s", dir) + +def renderFile(args, file, DEFAULT_OUTPUT_PATH): + logger.info("Generating files for: %s", str(pathlib.PurePath(file).name)) + with open(file, newline='') as csvfile: + data = csv.DictReader(csvfile, delimiter=';') + + campaignUuids = [] + for row in data: + campaignUuids.append(row["uuid"]) + + content = template.render(ServiceName = str(args.name), CampaignUuids = campaignUuids) + filename = pathlib.PurePath.joinpath(DEFAULT_OUTPUT_PATH, str(args.name) + ".request_attribute.tf") + + with open(filename, mode='w+', encoding="utf-8") as output: + output.write(content) + logger.info("Generated: %s", pathlib.PurePath(filename).name) + + +if __name__ == '__main__': + checkDirectories(DEFAULT_INPUT_PATH, DEFAULT_OUTPUT_PATH, DEFAULT_TEMPLATES_PATH) + logger.info("Using default input directory: %s", DEFAULT_INPUT_PATH) + files = sorted(pathlib.Path(DEFAULT_INPUT_PATH).glob("*.csv")) + + for f in files: + logger.info("File found: %s", str(f)) + renderFile(args, f, DEFAULT_OUTPUT_PATH) \ No newline at end of file diff --git a/templates/service.request_attribute.tf b/templates/service.request_attribute.tf new file mode 100644 index 0000000..b146bef --- /dev/null +++ b/templates/service.request_attribute.tf @@ -0,0 +1,113 @@ +resource "dynatrace_request_attribute" "{{ServiceName}}" { + name = "{{ServiceName}}" + enabled = true + aggregation = "FIRST" + # confidential = false + data_type = "STRING" + normalization = "ORIGINAL" + # skip_personal_data_masking = false + {%- for campaignUuid in CampaignUuids %} + data_sources { + enabled = true + source = "METHOD_PARAM" + technology = "JAVA" + methods { + argument_index = 1 + capture = "ARGUMENT" + deep_object_access = ".toString()" + method { + argument_types = [ "java.lang.Object", "de.audi.acdc.connectors.common.messages.MessageOffset", "de.audi.acdc.connectors.common.messages.MessageMetadata", "de.audi.acdc.platform.telemetry.api.TelemetryContext" ] + class_name = "de.audi.acdc.connectors.common.messages.IncomingMessage$" + method_name = "apply" + return_type = "de.audi.acdc.connectors.common.messages.IncomingMessage" + visibility = "PUBLIC" + } + } + methods { + argument_index = 1 + capture = "ARGUMENT" + deep_object_access = ".toString()" + method { + argument_types = [ "java.lang.Object", "de.audi.acdc.connectors.common.messages.MessageOffset", "long", "de.audi.acdc.connectors.common.messages.MessageMetadata", "de.audi.acdc.platform.telemetry.api.TelemetryContext" ] + class_name = "de.audi.acdc.connectors.common.messages.IncomingMessage$" + method_name = "apply" + return_type = "de.audi.acdc.connectors.common.messages.IncomingMessage" + visibility = "PUBLIC" + } + } + methods { + argument_index = 1 + capture = "ARGUMENT" + deep_object_access = ".toString()" + method { + argument_types = [ "java.lang.Object", "de.audi.acdc.connectors.common.messages.MessageOffset", "de.audi.acdc.platform.telemetry.api.TelemetryContext" ] + class_name = "de.audi.acdc.connectors.common.messages.IncomingMessage$" + method_name = "apply" + return_type = "de.audi.acdc.connectors.common.messages.IncomingMessage" + visibility = "PUBLIC" + } + } + value_processing { + # split_at = "" + # trim = false + value_extractor_regex = ",([0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}),\\w{32}" + value_condition { + # negate = false + operator = "CONTAINS" + value = "{{campaignUuid}}" + } + } + } + data_sources { + enabled = true + source = "METHOD_PARAM" + technology = "JAVA" + methods { + argument_index = 1 + capture = "ARGUMENT" + deep_object_access = ".toString()" + method { + argument_types = [ "java.lang.Object", "de.audi.acdc.connectors.common.messages.MessageOffset", "int", "long", "long", "de.audi.acdc.platform.telemetry.api.TelemetryContext" ] + class_name = "de.audi.acdc.connectors.common.messages.OutgoingMessage$" + method_name = "apply" + return_type = "de.audi.acdc.connectors.common.messages.OutgoingMessage" + visibility = "PUBLIC" + } + } + methods { + argument_index = 1 + capture = "ARGUMENT" + deep_object_access = ".toString()" + method { + argument_types = [ "java.lang.Object", "de.audi.acdc.connectors.common.messages.MessageOffset", "int", "long", "long", "long", "de.audi.acdc.connectors.common.messages.MessageMetadata", "de.audi.acdc.platform.telemetry.api.TelemetryContext" ] + class_name = "de.audi.acdc.connectors.common.messages.OutgoingMessage$" + method_name = "apply" + return_type = "de.audi.acdc.connectors.common.messages.OutgoingMessage" + visibility = "PUBLIC" + } + } + methods { + argument_index = 1 + capture = "ARGUMENT" + deep_object_access = ".toString()" + method { + argument_types = [ "java.lang.Object", "de.audi.acdc.connectors.common.messages.MessageOffset", "int", "long", "long", "de.audi.acdc.connectors.common.messages.MessageMetadata", "de.audi.acdc.platform.telemetry.api.TelemetryContext" ] + class_name = "de.audi.acdc.connectors.common.messages.OutgoingMessage$" + method_name = "apply" + return_type = "de.audi.acdc.connectors.common.messages.OutgoingMessage" + visibility = "PUBLIC" + } + } + value_processing { + # split_at = "" + # trim = false + value_extractor_regex = ",([0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}),\\w{32}" + value_condition { + # negate = false + operator = "CONTAINS" + value = "{{campaignUuid}}" + } + } + } + {%- endfor %} +}