From 5e7cd8f009fa78b39cf3114f62f0697405364bdc Mon Sep 17 00:00:00 2001 From: Debora Benedetto <debora.benedetto@hpe.com> Date: Thu, 14 Jul 2022 11:40:55 +0200 Subject: [PATCH] add automation for terraform config file generation --- controller/Orchestrator.py | 6 +++--- icgparser/DomlParserUtilities.py | 3 +++ icgparser/ModelParser.py | 21 +++++++++++++++++++ input_file_generated/ir.json | 15 +++++++++++++ plugin/PluginUtility.py | 8 +++++++ plugin/TemplateUtils.py | 4 ++-- plugin/TerraformPlugin.py | 8 +++++-- template-location.properties | 1 + templates/terraform/open_stack/config.tpl | 14 +++++++++++++ .../open_stack/virtual_machine_out.tpl | 2 +- 10 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 plugin/PluginUtility.py create mode 100644 templates/terraform/open_stack/config.tpl diff --git a/controller/Orchestrator.py b/controller/Orchestrator.py index 29af7c8..62897d6 100644 --- a/controller/Orchestrator.py +++ b/controller/Orchestrator.py @@ -30,9 +30,9 @@ def choose_plugin(parameters, template_generated_folder): for step in parameters["steps"]: if step["programming_language"] == "ansible": logging.info("Ansible Plugin chosen") - metadata_root_folder["iac"].append("ansible") - input_data = step["data"] - AnsiblePlugin.create_files(input_data, template_generated_folder) + # metadata_root_folder["iac"].append("ansible") + # input_data = step["data"] + # AnsiblePlugin.create_files(input_data, template_generated_folder) elif step["programming_language"] == "terraform": logging.info("Terraform Plugin chosen") metadata_root_folder["iac"].append("terraform") diff --git a/icgparser/DomlParserUtilities.py b/icgparser/DomlParserUtilities.py index 0f1b76f..0125b8b 100644 --- a/icgparser/DomlParserUtilities.py +++ b/icgparser/DomlParserUtilities.py @@ -85,6 +85,9 @@ def save_references_info(from_object, to_object): ## TODO refactoring update_missing_parsed_resources(reference_object, reference=ref, is_to_be_parsed=True) return to_object +def get_references(from_object): + refs = from_object.eClass.eAllReferences() + return list(refs) def save_inner_components(from_object, to_object): inner_components = from_object.eAllContents() diff --git a/icgparser/ModelParser.py b/icgparser/ModelParser.py index 7666d79..1dd5daa 100644 --- a/icgparser/ModelParser.py +++ b/icgparser/ModelParser.py @@ -76,13 +76,34 @@ def parse_infrastructural_objects(doml_model): infra_object_step = include_missing_objects_from_infrastructure_layer(infra_object_step) return infra_object_step +def parse_application_layer(doml_model): + logging.info("DOML parsing: getting active configuration") + application_object_step = {"programming_language": "ansible", "data": {}} + active_configuration = doml_model.activeConfiguration + logging.info(f"Found active configuration '{active_configuration.name}'") + for deployment in list(active_configuration.deployments): + deployment_component_name = deployment.component.name + logging.info(f'Parsing deployment for component {deployment_component_name}') + refs = DomlParserUtilities.get_references(deployment) + object_list_representation = [] + for ref in refs: + object_representation = {} + obj = deployment.eGet(ref.name) + object_representation = DomlParserUtilities.save_annotations(obj, object_representation) + object_representation = DomlParserUtilities.save_attributes(obj, object_representation) + object_list_representation.append(object_representation) + + application_object_step["data"][deployment.component.name] = object_list_representation + return application_object_step def create_intermediate_representation(model_loaded): model_name = model_loaded.name output_path = OUTPUT_BASE_DIR_PATH + model_name + "/" intermediate_representation_steps = [] infra_object_step = parse_infrastructural_objects(model_loaded) + application_step = parse_application_layer(model_loaded) intermediate_representation_steps.append(infra_object_step) + intermediate_representation_steps.append(application_step) intermediate_representation = { "output_path": output_path, "steps": intermediate_representation_steps diff --git a/input_file_generated/ir.json b/input_file_generated/ir.json index 3a81c9d..5dc101a 100644 --- a/input_file_generated/ir.json +++ b/input_file_generated/ir.json @@ -94,6 +94,21 @@ ] }, "programming_language": "terraform" + }, + { + "data": { + "nginx": [ + { + "name": "vm1", + "os": "ubuntu-20.04.3" + }, + { + "name": "nginx", + "source_code": "/usr/share/nginx/html/index.html" + } + ] + }, + "programming_language": "ansible" } ] } \ No newline at end of file diff --git a/plugin/PluginUtility.py b/plugin/PluginUtility.py new file mode 100644 index 0000000..1b4326e --- /dev/null +++ b/plugin/PluginUtility.py @@ -0,0 +1,8 @@ +from plugin import TemplateUtils + + +def createExecutionFileInstructions(iac_language, key, data): + template_for_config_path = TemplateUtils.find_template_path(iac_language, key, "config") + template_for_config = TemplateUtils.read_template(template_for_config_path) + template_for_config_path_edited = TemplateUtils.edit_template(template_for_config, data) + return template_for_config_path_edited diff --git a/plugin/TemplateUtils.py b/plugin/TemplateUtils.py index 6eeb561..c74d427 100644 --- a/plugin/TemplateUtils.py +++ b/plugin/TemplateUtils.py @@ -23,7 +23,7 @@ def find_template_path(iac_language, key, resource_name): def edit_template(template, parameters: dict): - logging.info("Starting editing template") + logging.info(f"Starting editing template '{template}'") template.globals['context'] = get_context template.globals['callable'] = callable render = template.render(parameters) @@ -47,4 +47,4 @@ def write_template(template, output_path_file): file = open(output_path_file, "w+") file.write(template) logging.info("Writing file at: '%s'", output_path_file) - file.close() + file.close() \ No newline at end of file diff --git a/plugin/TerraformPlugin.py b/plugin/TerraformPlugin.py index 6b7facf..ef165ce 100644 --- a/plugin/TerraformPlugin.py +++ b/plugin/TerraformPlugin.py @@ -1,10 +1,13 @@ import logging -from plugin import TemplateUtils +from plugin import TemplateUtils, PluginUtility def create_files(parameters, output_path): language = "terraform" provider = parameters["provider"] + + config_file = PluginUtility.createExecutionFileInstructions(language, provider, parameters) + resources = parameters.keys() terraform_main_file = create_init_file(language, provider) terraform_out_file = "" @@ -27,11 +30,12 @@ def create_files(parameters, output_path): # resource = parameters[resource_name] template_out_filled = TemplateUtils.edit_template(template_out, resource_params) terraform_out_file = terraform_out_file + template_out_filled + "\n" - main_file_stored_path = output_path + "/main.tf" TemplateUtils.write_template(terraform_main_file, main_file_stored_path) output_file_stored_path = output_path + "/output.tf" TemplateUtils.write_template(terraform_out_file, output_file_stored_path) + config_file_stored_path = output_path + "/config.yaml" + TemplateUtils.write_template(config_file, config_file_stored_path) logging.info("Terraform main file available at: {}".format(main_file_stored_path)) logging.info(f"Terraform output file available at {output_file_stored_path}") diff --git a/template-location.properties b/template-location.properties index 2a462fc..f6a4c4a 100644 --- a/template-location.properties +++ b/template-location.properties @@ -1,5 +1,6 @@ [terraform.openstack] init = templates/terraform/open_stack/init.tpl +config = templates/terraform/open_stack/config.tpl vms = templates/terraform/open_stack/virtual_machine.tpl vms_out = templates/terraform/open_stack/virtual_machine_out.tpl networks = templates/terraform/open_stack/network.tpl diff --git a/templates/terraform/open_stack/config.tpl b/templates/terraform/open_stack/config.tpl new file mode 100644 index 0000000..83b68b7 --- /dev/null +++ b/templates/terraform/open_stack/config.tpl @@ -0,0 +1,14 @@ +--- +engine: terraform +input: + - OS_USERNAME + - OS_PASSWORD + - OS_AUTH_URL + - OS_PROJECT_NAME +output: +{% for vm in vms %} + - instance_server_public_key_{{ vm.vm_key_name }} + - instance_server_private_key_{{ vm.vm_key_name }} + - instance_ip_{{ vm.vm_name }} +{% endfor %} +... diff --git a/templates/terraform/open_stack/virtual_machine_out.tpl b/templates/terraform/open_stack/virtual_machine_out.tpl index 95fa933..e39fa9f 100644 --- a/templates/terraform/open_stack/virtual_machine_out.tpl +++ b/templates/terraform/open_stack/virtual_machine_out.tpl @@ -6,6 +6,6 @@ output "instance_server_private_key_{{ vm_key_name }}" { value = openstack_compute_keypair_v2.{{ vm_key_name }}.private_key } -output "instance_ip" { +output "instance_ip_{{ vm_name }}" { value = openstack_compute_floatingip_associate_v2.{{ infra_element_name ~ "_floating_ip_association" }}.floating_ip } \ No newline at end of file -- GitLab