From c55f70b5de5bb5ce19527592db6430c3bf485890 Mon Sep 17 00:00:00 2001
From: Attila Farkas <x394097@fi.muni.cz>
Date: Tue, 12 Nov 2019 11:19:20 +0100
Subject: [PATCH] separate user ansible files from basic configuration

---
 modules/file_generator.py      | 50 +++++++++++++++++++++-------------
 templates/device_configuration | 22 +++++++++++++--
 templates/hosts                |  2 +-
 templates/playbook             | 49 +++++----------------------------
 templates/separate_hosts       |  2 ++
 templates/user_hosts           |  8 ++++++
 templates/user_separate_hosts  |  8 ++++++
 templates/vagrantfile          | 12 +++++++-
 8 files changed, 87 insertions(+), 66 deletions(-)
 create mode 100644 templates/user_hosts
 create mode 100644 templates/user_separate_hosts

diff --git a/modules/file_generator.py b/modules/file_generator.py
index a138068..d73861e 100644
--- a/modules/file_generator.py
+++ b/modules/file_generator.py
@@ -23,23 +23,23 @@ def _generate_file(filename, output_string):
         print("Error: cannot write to this location.")
 
 
-def _create_role_directory(role_name):
+def _create_role_directory(role_name, provisioning_dir):
     """ Creates directory structure for a role. """
 
     try:
-        os.mkdir("provisioning")
+        os.mkdir(provisioning_dir)
     except FileExistsError:
         pass
     try:
-        os.mkdir("provisioning/roles")
+        os.mkdir(provisioning_dir + "/roles")
     except FileExistsError:
         pass
     try:
-        os.mkdir("provisioning/roles/" + role_name)
+        os.mkdir(provisioning_dir + "/roles/" + role_name)
     except FileExistsError:
         pass
     try:
-        os.mkdir("provisioning/roles/" + role_name +"/tasks")
+        os.mkdir(provisioning_dir + "/roles/" + role_name +"/tasks")
     except FileExistsError:
         pass
 
@@ -71,10 +71,9 @@ def _generate_playbook(definitions):
 
     host_map = create_host_map(definitions["net_mappings"], definitions["router_mappings"], definitions["hosts"])
     network = create_network_map(definitions)
-    network_ips = create_network_ips(definitions["networks"])
     
     template = _load_template("playbook")
-    output = template.render(hosts=host_map, routers=network, network_ips=network_ips, border_router_name = BORDER_ROUTER_NAME)
+    output = template.render(hosts=host_map, routers=network)
 
     try:
         os.mkdir("provisioning")
@@ -92,14 +91,14 @@ def _generate_device_configuration(definitions):
     network_ips = create_network_ips(definitions["networks"])
 
     template = _load_template("device_configuration")
-    output = template.render(hosts=host_map, routers=network, network_ips=network_ips)
+    output = template.render(hosts=host_map, routers=network, network_ips=network_ips, border_router_name = BORDER_ROUTER_NAME)
 
     try:
-        os.mkdir("provisioning")
+        os.mkdir("base_provisioning")
     except FileExistsError:
         pass
 
-    _generate_file("./provisioning/device_configuration.yml", output)
+    _generate_file("./base_provisioning/device_configuration.yml", output)
 
 
 def _generate_hosts_role(definitions):
@@ -112,7 +111,13 @@ def _generate_hosts_role(definitions):
     template = _load_template("hosts")
     output = template.render(hosts=host_map, routers=network)
 
-    _create_role_directory("hosts")
+    _create_role_directory("hosts", "base_provisioning")
+    _generate_file("./base_provisioning/roles/hosts/tasks/main.yml", output)
+    
+    user_template = _load_template("user_hosts")
+    user_output = template.render()
+
+    _create_role_directory("hosts", "provisioning")
     _generate_file("./provisioning/roles/hosts/tasks/main.yml", output)
 
 
@@ -125,13 +130,21 @@ def _generate_separate_hosts_role(definitions):
 
         for host_attributes in host_map:
             if host_attributes["host_name"] == host["name"]:
+                host_name = host_attributes["host_name"]
                 router_ip = host_attributes["router_ip"]
                 interface = host_attributes["interface"]
 
         template = _load_template("separate_hosts")
-        output = template.render(router_ip=router_ip, interface=interface)
+        output = template.render(host_name=host_name, router_ip=router_ip, interface=interface)
+
+        _create_role_directory(host["name"], "base_provisioning")
+        _generate_file("./base_provisioning/roles/" + host["name"]  + "/tasks/main.yml", output)
+
+
+        template = _load_template("user_separate_hosts")
+        output = template.render(host_name=host_name)
 
-        _create_role_directory(host["name"])
+        _create_role_directory(host["name"], "provisioning")
         _generate_file("./provisioning/roles/" + host["name"]  + "/tasks/main.yml", output)
 
 def _generate_routers_role(definitions):
@@ -148,8 +161,8 @@ def _generate_routers_role(definitions):
     template = _load_template("routers")
     output = template.render(hosts=host_map, routers=network, border_router_ip=BORDER_ROUTER_IP)
 
-    _create_role_directory("routers")
-    _generate_file("./provisioning/roles/routers/tasks/main.yml", output)
+    _create_role_directory("routers", "base_provisioning")
+    _generate_file("./base_provisioning/roles/routers/tasks/main.yml", output)
 
 
 def _find_cidr(network_name, definitions):
@@ -187,16 +200,15 @@ def _generate_br_role(definitions):
     template = _load_template("br")
     output = template.render(hosts = host_map, routers=network, br_routes=routers_in_br_network, border_router_name=BORDER_ROUTER_NAME, border_router_public_ip=BORDER_ROUTER_PUBLIC_IP)
 
-    _create_role_directory("br")
-    _generate_file("./provisioning/roles/br/tasks/main.yml", output)
+    _create_role_directory("br", "base_provisioning")
+    _generate_file("./base_provisioning/roles/br/tasks/main.yml", output)
 
 
 def generate_ansible_files(device_definitions):
     """ Generates files for ansible. """
     
     _generate_playbook(device_definitions)
-    # uncomment after the new version of ansible can be used
-    # _generate_device_configuration(device_definitions)
+    _generate_device_configuration(device_definitions)
     _generate_hosts_role(device_definitions)
     _generate_separate_hosts_role(device_definitions)
     _generate_routers_role(device_definitions)
diff --git a/templates/device_configuration b/templates/device_configuration
index 73a852f..e8ba832 100644
--- a/templates/device_configuration
+++ b/templates/device_configuration
@@ -7,18 +7,34 @@
   roles:
     - hosts
 
+{% for host in hosts %}
+- name: Configuring host {{ host.host_name }} separately
+  hosts: {{ host.host_name }}
+  become: yes
+  roles:
+    - {{ host.host_name }}
+
+{% endfor %}
 {% for host in hosts %}
 - name: Configuring host {{ host.host_name }}
   hosts: {{ host.host_name }}
   become: yes
   tasks:
-  - name: Change default gateway
-    command: route add default gw {{ host.router_ip }} {{ host.interface }}
+{% for network_ip in network_ips %}
+  - name: Add gateway for {{ network_ip }}
+    command: route add -net {{ network_ip }} gw {{ host.router_ip }} {{ host.interface }}
+{% endfor %}
 
 {% endfor %}
 - name: Configuring all routers
-  hosts: {{ routers|map(attribute='router_name')|unique|join(',') }}
+  hosts: {{ routers|map(attribute='router_name')|unique|reject('eq', border_router_name)|join(',') }}
   become: yes
   roles:
     - routers
+
+- name: Configuring border router
+  hosts: {{ border_router_name }}
+  become: yes
+  roles:
+    - br
 ...
diff --git a/templates/hosts b/templates/hosts
index 4317ae0..e9254f1 100644
--- a/templates/hosts
+++ b/templates/hosts
@@ -1,5 +1,5 @@
 ---
-# Configuration of all host devices
+# Basic configuration of all host devices
 
 - name: Install net-tools
   command: apt install net-tools
diff --git a/templates/playbook b/templates/playbook
index 93ee8e7..7f3e1c7 100644
--- a/templates/playbook
+++ b/templates/playbook
@@ -1,47 +1,12 @@
 ---
-# Main ansible playbook
-
-#- import_playbook: device_configuration.yml - for new version
-
-- name: Configuring all hosts
-  hosts: {{ hosts|map(attribute='host_name')|unique|join(',') }}
-  become: yes
-  roles:
-    - hosts
-
-{% for host in hosts %}
-- name: Configuring host {{ host.host_name }} separately
-  hosts: {{ host.host_name }}
-  become: yes
-  roles:
-    - {{ host.host_name }}
-
-{% endfor %}
-{% for host in hosts %}
-- name: Configuring host {{ host.host_name }}
-  hosts: {{ host.host_name }}
-  become: yes
-  tasks:
-{% for network_ip in network_ips %} 
-  - name: Add gateway for {{ network_ip }}
-    command: route add -net {{ network_ip }} gw {{ host.router_ip }} {{ host.interface }}
-{% endfor %}
-
-
-{% endfor %}
-- name: Configuring all routers
-  hosts: {{ routers|map(attribute='router_name')|unique|reject('eq', border_router_name)|join(',') }}
-  become: yes
-  roles:
-    - routers
-
-- name: Configuring border router
-  hosts: {{ border_router_name }}
-  become: yes
-  roles:
-    - br
-
+# Main user ansible playbook
 # Write your custom configuration here:
 
+- name: Hello world
+  hosts: all
+  tasks:
 
+    - name: print hello world
+      debug:
+        msg: "Hello World"
 ...
diff --git a/templates/separate_hosts b/templates/separate_hosts
index 3bf7004..42e3f80 100644
--- a/templates/separate_hosts
+++ b/templates/separate_hosts
@@ -1,4 +1,6 @@
 ---
+# Role for the host {{ host_name }}
+
 - name: Add default path to router
   command: route add default gw {{ router_ip }} {{ interface }}
 ...
diff --git a/templates/user_hosts b/templates/user_hosts
new file mode 100644
index 0000000..0dccf70
--- /dev/null
+++ b/templates/user_hosts
@@ -0,0 +1,8 @@
+---
+# This is a role for all hosts.
+# You can write your tasks here.
+# These changes will affect all hosts.
+
+
+
+...
diff --git a/templates/user_separate_hosts b/templates/user_separate_hosts
new file mode 100644
index 0000000..f49a8ba
--- /dev/null
+++ b/templates/user_separate_hosts
@@ -0,0 +1,8 @@
+---
+# This is a role for the host {{ host_name }}.
+# You can write your tasks here.
+# These changes will affect only the host {{ host_name }}.
+
+
+
+...
diff --git a/templates/vagrantfile b/templates/vagrantfile
index e51a3ae..946446c 100644
--- a/templates/vagrantfile
+++ b/templates/vagrantfile
@@ -19,7 +19,17 @@ Vagrant.configure("2") do |config|
 {{ printAttributes(name) }}  end
 {% endfor %}
 
-  # configuration of devices with ansible
+  # basic ansible configuration of devices and networks
+  config.vm.provision :ansible{% if ansible_local %}_local{% endif %} do |ansible|
+    ansible.playbook = "base_provisioning/device_configuration.yml"
+    ansible.verbose = true
+    ansible.extra_vars = {
+      ansible_python_interpreter: "/usr/bin/python3",
+    }
+  end
+
+
+  # user configuration of devices with ansible
   config.vm.provision :ansible{% if ansible_local %}_local{% endif %} do |ansible|
     ansible.playbook = "provisioning/playbook.yml"
     ansible.verbose = true
-- 
GitLab