From 68383310fa46fb9b8a595c9e80bcf3760dd280e8 Mon Sep 17 00:00:00 2001
From: Debora Benedetto <debora.benedetto@hpe.com>
Date: Thu, 5 May 2022 12:16:58 +0200
Subject: [PATCH] Add config.yaml files generation and update readme with
 folders structure info

---
 README.md                                     |  9 ++-
 controller/Orchestrator.py                    | 23 ++++--
 controller/test_Orchestrator.py               |  7 ++
 icgparser/DomlParserUtilities.py              |  3 +
 input_file_generated/ir.json                  | 73 ++++---------------
 .../nginx_openstack/config.yaml               |  2 +
 .../nginx_openstack/terraform/main.tf         | 60 ++-------------
 plugin/TerraformPlugin.py                     |  2 +-
 templates/terraform/open_stack/init.tpl       |  6 +-
 9 files changed, 64 insertions(+), 121 deletions(-)
 create mode 100644 controller/test_Orchestrator.py
 create mode 100644 output_files_generated/nginx_openstack/config.yaml

diff --git a/README.md b/README.md
index dbc0b8e..cc6f4c8 100644
--- a/README.md
+++ b/README.md
@@ -49,4 +49,11 @@ Usage: python main.py [-h] [-d dir] model
 
 Example:
 
-` py .\main.py -d icgparser/doml --single icgparser/doml/nginx-openstack_v2.domlx`
\ No newline at end of file
+` py .\main.py -d icgparser/doml --single icgparser/doml/nginx-openstack_v2.domlx`
+
+Folders Structure
+------------
+- _output_file_example_: in this folder there is the output of the ICG tested for the examples considered during the PIACERE interations. The output files are tested and represents how the ICG output should be.
+- _output_files_generated_: in this folder there is the output generated by the execution of the ICG 
+- _input_file_example_: in this folder there is an example of how the ICG intermediate representation should be for the examples considered during the PIACERE interations
+- _input_file_generated_: in this folder there is the intermediate representation generated by the execution of the ICG 
\ No newline at end of file
diff --git a/controller/Orchestrator.py b/controller/Orchestrator.py
index f929900..5048bfd 100644
--- a/controller/Orchestrator.py
+++ b/controller/Orchestrator.py
@@ -2,6 +2,8 @@ import json
 import logging
 import tarfile
 import uuid
+import yaml
+
 from icgparser import ModelParser
 from plugin import AnsiblePlugin, TerraformPlugin
 
@@ -22,24 +24,31 @@ def create_infrastructure_files(intermediate_representation: dict):
 def choose_plugin(parameters, template_generated_folder):
     # os.system('rm -f /opt/output_files_generated/*')
     logging.info("Choosing plugin")
+    metadata_root_folder = {"iac": []}
     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)
         elif step["programming_language"] == "terraform":
             logging.info("Terraform Plugin chosen")
+            metadata_root_folder["iac"].append("terraform")
             input_data = step["data"]
-            TerraformPlugin.create_files(input_data, template_generated_folder)
-
-
-def create_temp_file_for_model(model, output_folder):
-    logging.info(f"Writing model file in temp folder at {output_folder} for parsing")
+            iac_output_folder = template_generated_folder + "terraform"
+            plugin_metadata = {"input": ["openstack_username", "openstack_password", "openstack_auth_url"],
+                               "output": [], "engine": "terraform"}
+            save_file(plugin_metadata, iac_output_folder + "/config.yaml", output_extensions="YAML")
+            TerraformPlugin.create_files(input_data, iac_output_folder)
+    save_file(metadata_root_folder, template_generated_folder + "/config.yaml", output_extensions="YAML")
 
 
-def save_file(data, file_path):
+def save_file(data, file_path, output_extensions="json"):
+    logging.debug(f"Saving data: {data} at {file_path}")
     logging.info(f"Saving data at: {file_path}")
     file = open(file_path, "w")
+    if isinstance(data, dict) and output_extensions == "YAML":
+        data = yaml.dump(data)
     if isinstance(data, dict):
         data = json.dumps(data, indent=2, sort_keys=True)
     print(data)
@@ -124,7 +133,7 @@ def create_iac_from_doml(model, is_multiecore_metamodel, metamodel_directory):
     """
     logging.info("Creating iac files: parse and plugins will be called")
     model_path = create_temp_model_file(model_xml=model)
-    ## TODO: same as create_iac_from_doml_path a part from the model storage in xml
+    ## TODO: same as def create_iac_from_doml_path a part from the model storage in xml
     intermediate_representation = create_intermediate_representation(model_path, is_multiecore_metamodel,
                                                                      metamodel_directory)
     template_generated_folder = create_iac_from_intermediate_representation(intermediate_representation)
diff --git a/controller/test_Orchestrator.py b/controller/test_Orchestrator.py
new file mode 100644
index 0000000..d268942
--- /dev/null
+++ b/controller/test_Orchestrator.py
@@ -0,0 +1,7 @@
+from unittest import TestCase
+
+
+class TestOrchestrator(TestCase):
+
+    def test_create_iac_from_doml(self):
+        self.fail()
diff --git a/icgparser/DomlParserUtilities.py b/icgparser/DomlParserUtilities.py
index 9fb3eab..8da07b8 100644
--- a/icgparser/DomlParserUtilities.py
+++ b/icgparser/DomlParserUtilities.py
@@ -46,6 +46,9 @@ def save_attributes(from_object, to_object, skip_component_name=False):
             if skip_component_name and attribute.name == "name":
                 key = "infra_element_name"
                 print(f'Renaming attributes {attribute.name} from {from_object.name} into {key}')
+            elif attribute.name == "name":
+                key = "concrete_element_name"
+                print(f'Renaming attributes {attribute.name} from {from_object.name} into {key}')
             value = from_object.eGet(attribute.name)
             if isinstance(value, EOrderedSet):
                 value = list(value)
diff --git a/input_file_generated/ir.json b/input_file_generated/ir.json
index 5c701e4..0a8ce39 100644
--- a/input_file_generated/ir.json
+++ b/input_file_generated/ir.json
@@ -3,91 +3,50 @@
   "steps": [
     {
       "data": {
-        "computingGroup": [
+        "credentials": [
           {
-            "cidr": [
-              "0.0.0.0/0"
-            ],
-            "fromPort": -1,
-            "kind": "EGRESS",
-            "name": "out_all",
-            "protocol": "-1",
-            "toPort": -1
-          },
-          {
-            "cidr": [
-              "0.0.0.0/0"
-            ],
-            "fromPort": 80,
-            "kind": "INGRESS",
-            "name": "http",
-            "protocol": "tcp",
-            "toPort": 80
-          },
-          {
-            "cidr": [
-              "0.0.0.0/0"
-            ],
-            "fromPort": 443,
-            "kind": "INGRESS",
-            "name": "https",
-            "protocol": "tcp",
-            "toPort": 443
-          },
-          {
-            "cidr": [
-              "0.0.0.0/0"
-            ],
-            "fromPort": 22,
-            "kind": "INGRESS",
-            "name": "ssh",
-            "protocol": "tcp",
-            "toPort": 22
+            "algorithm": "RSA",
+            "bits": 4096,
+            "concrete_element_name": "ssh_key",
+            "keyfile": "/home/user1/.ssh/openstack.key",
+            "user": "ubuntu"
           }
         ],
         "networks": [
           {
             "addressRange": "16.0.0.0/24",
+            "concrete_element_name": "concrete_net",
             "infra_element_name": "net1",
-            "name": "concrete_net",
+            "name": "ostack2",
             "protocol": "tcp/ip"
           }
         ],
         "provider": "openstack",
         "vmImages": [
           {
+            "concrete_element_name": "concrete_vm_image",
             "infra_element_name": "v_img",
             "kind": "SCRIPT",
-            "name": "concrete_vm_image"
+            "name": "ubuntu-20.04.3"
           }
         ],
         "vms": [
           {
+            "concrete_element_name": "concrete_vm",
             "credentials": "ssh_key",
             "generatedFrom": "v_img",
             "group": "sg",
             "i1": {
               "associated": "sg",
               "belongsTo": "net1",
-              "endPoint": "16.0.0.1",
-              "name": "i1"
+              "concrete_element_name": "i1",
+              "endPoint": "16.0.0.1"
             },
             "infra_element_name": "vm1",
-            "name": "concrete_vm",
             "os": "ubuntu-20.04.3",
-            "vm_Availability": 98,
-            "vm_Cost_Currency": 4.53,
-            "vm_Frequency_per_Core": 1500,
-            "vm_Instance_Storage": 40,
-            "vm_Memory": 0.5,
-            "vm_Optimized_for": "GEPU",
-            "vm_Region": "00EU",
-            "vm_Response_time_Virtual_Machine_Performance": 3,
-            "vm_Virtual_CPU_Cores": 1,
-            "vm_Zone": "IEEU",
-            "vm_flavor": "t2.nano",
-            "vm_provider_OU": "AMAZ",
-            "vm_public_IP_type": "IPV4"
+            "vm_flavor": "small",
+            "vm_key_name": "user1",
+            "vm_name": "nginx-host"
           }
         ]
       },
diff --git a/output_files_generated/nginx_openstack/config.yaml b/output_files_generated/nginx_openstack/config.yaml
new file mode 100644
index 0000000..cb3ec8c
--- /dev/null
+++ b/output_files_generated/nginx_openstack/config.yaml
@@ -0,0 +1,2 @@
+iac:
+- terraform
diff --git a/output_files_generated/nginx_openstack/terraform/main.tf b/output_files_generated/nginx_openstack/terraform/main.tf
index a85074e..bf1652f 100644
--- a/output_files_generated/nginx_openstack/terraform/main.tf
+++ b/output_files_generated/nginx_openstack/terraform/main.tf
@@ -10,10 +10,10 @@ required_version = ">= 0.14.0"
 
 # Configure the OpenStack Provider
 provider "openstack" {
-  user_name   = var.username
+  user_name   = var.openstack_username
   tenant_name = "admin"
-  password    = var.password
-  auth_url    = var.auth_url
+  password    = var.openstack_password
+  auth_url    = var.openstack_auth_url
   insecure    = true
 }
 
@@ -32,9 +32,9 @@ data "openstack_networking_secgroup_v2" "default" {
 }
 # Create virtual machine
 resource "openstack_compute_instance_v2" "vm1" {
-  name        = ""
+  name        = "nginx-host"
   image_name  = "ubuntu-20.04.3"
-  flavor_name = "t2.nano"
+  flavor_name = "small"
   key_pair    = openstack_compute_keypair_v2.ssh_key.name
   network {
     port = openstack_networking_port_v2.net1.id
@@ -63,12 +63,12 @@ resource "openstack_compute_floatingip_associate_v2" "vm1_floating_ip_associatio
 
 # Create Network
 resource "openstack_networking_network_v2" "net1" {
-  name = "concrete_net"
+  name = "ostack2"
 }
 
 # Create Subnet
 resource "openstack_networking_subnet_v2" "net1_subnet" {
-  name            = "concrete_net_subnet"
+  name            = "ostack2_subnet"
   network_id      = openstack_networking_network_v2.net1.id
   cidr            = "16.0.0.0/24"
   dns_nameservers = ["8.8.8.8", "8.8.8.4"]
@@ -76,7 +76,7 @@ resource "openstack_networking_subnet_v2" "net1_subnet" {
 
 # Attach networking port
 resource "openstack_networking_port_v2" "net1" {
-  name           = "concrete_net"
+  name           = "ostack2"
   network_id     = openstack_networking_network_v2.net1.id
   admin_state_up = true
   security_group_ids = [
@@ -98,47 +98,3 @@ resource "openstack_networking_router_interface_v2" "net1_router_interface" {
   subnet_id = openstack_networking_subnet_v2.net1_subnet.id
 }
 
-resource "openstack_compute_secgroup_v2" "out_all" {
-  name        = "out_all"
-  description  = "Security group rule for port -1"
-  rule {
-    from_port   = -1
-    to_port     = -1
-    ip_protocol = "-1"
-    cidr        = "0.0.0.0/0"
-  }
-}
-
-resource "openstack_compute_secgroup_v2" "http" {
-  name        = "http"
-  description  = "Security group rule for port 80"
-  rule {
-    from_port   = 80
-    to_port     = 80
-    ip_protocol = "tcp"
-    cidr        = "0.0.0.0/0"
-  }
-}
-
-resource "openstack_compute_secgroup_v2" "https" {
-  name        = "https"
-  description  = "Security group rule for port 443"
-  rule {
-    from_port   = 443
-    to_port     = 443
-    ip_protocol = "tcp"
-    cidr        = "0.0.0.0/0"
-  }
-}
-
-resource "openstack_compute_secgroup_v2" "ssh" {
-  name        = "ssh"
-  description  = "Security group rule for port 22"
-  rule {
-    from_port   = 22
-    to_port     = 22
-    ip_protocol = "tcp"
-    cidr        = "0.0.0.0/0"
-  }
-}
-
diff --git a/plugin/TerraformPlugin.py b/plugin/TerraformPlugin.py
index 4ca1617..db19c21 100644
--- a/plugin/TerraformPlugin.py
+++ b/plugin/TerraformPlugin.py
@@ -16,7 +16,7 @@ def create_files(parameters, output_path):
                 # resource = parameters[resource_name]
                 template_filled = TemplateUtils.edit_template(template, resource_params)
                 terraform_file = terraform_file + template_filled + "\n"
-    output_file_path = output_path + "/".join([language, "main.tf"])
+    output_file_path = output_path + "/main.tf"
     TemplateUtils.write_template(terraform_file, output_file_path)
     logging.info("File available at: {}".format(output_path))
 
diff --git a/templates/terraform/open_stack/init.tpl b/templates/terraform/open_stack/init.tpl
index 9b5464e..040b726 100644
--- a/templates/terraform/open_stack/init.tpl
+++ b/templates/terraform/open_stack/init.tpl
@@ -10,10 +10,10 @@ required_version = ">= 0.14.0"
 
 # Configure the OpenStack Provider
 provider "openstack" {
-  user_name   = var.username
+  user_name   = var.openstack_username
   tenant_name = "admin"
-  password    = var.password
-  auth_url    = var.auth_url
+  password    = var.openstack_password
+  auth_url    = var.openstack_auth_url
   insecure    = true
 }
 
-- 
GitLab