From 0dbacc342c2dd721ba8b96a9dc13b1fa0d4f8c49 Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@esss.se> Date: Fri, 13 Jul 2018 14:06:36 +0200 Subject: [PATCH] Add trigger ZTP configuration task JIRA INFRA-414 --- app/models.py | 17 +++++++ app/network/forms.py | 4 ++ app/network/views.py | 67 +++++++++++++++++++--------- app/settings.py | 1 + app/tasks.py | 23 ++++++++++ app/templates/network/view_host.html | 33 ++++++++------ 6 files changed, 112 insertions(+), 33 deletions(-) diff --git a/app/models.py b/app/models.py index 0afa49f..d3745fe 100644 --- a/app/models.py +++ b/app/models.py @@ -829,6 +829,23 @@ class Host(CreatedMixin, db.Model): except IndexError: return None + @property + def main_interface(self): + """Return the host main interface + + The main interface is the one that has the same name as the host + or the first one found + """ + for interface in self.interfaces: + if interface.name == self.name: + return interface + # No interface with the same name found... + # Return the first one + try: + return self.interfaces[0] + except IndexError: + return None + def __str__(self): return str(self.name) diff --git a/app/network/forms.py b/app/network/forms.py index f349683..208b05d 100644 --- a/app/network/forms.py +++ b/app/network/forms.py @@ -227,6 +227,10 @@ class CreateVMForm(CSEntryForm): self.memory.choices = utils.get_choices(current_app.config["VM_MEMORY_CHOICES"]) +class GenerateZTPConfigForm(CSEntryForm): + pass + + class AnsibleGroupForm(CSEntryForm): name = StringField( "name", diff --git a/app/network/views.py b/app/network/views.py index 4104bac..7b4f0c6 100644 --- a/app/network/views.py +++ b/app/network/views.py @@ -31,6 +31,7 @@ from .forms import ( NetworkScopeForm, DomainForm, CreateVMForm, + GenerateZTPConfigForm, AnsibleGroupForm, ) from ..extensions import db @@ -110,28 +111,54 @@ def create_host(): @login_required def view_host(name): host = models.Host.query.filter_by(name=name).first_or_404() - form = CreateVMForm() - if host.is_ioc: - form.cores.choices = utils.get_choices(current_app.config["VIOC_CORES_CHOICES"]) - form.memory.choices = utils.get_choices( - current_app.config["VIOC_MEMORY_CHOICES"] - ) - if form.validate_on_submit(): - if not current_user.is_admin: - flash(f"Only admin users are allowed to create a VM!", "info") - return redirect(url_for("network.view_host", name=name)) - else: - interface = host.interfaces[0] - task = tasks.trigger_vm_creation( - name, interface, int(form.memory.data) * 1000, form.cores.data + if host.device_type.name == "Network": + form = GenerateZTPConfigForm() + elif host.device_type.name.startswith("Virtual"): + form = CreateVMForm() + if host.is_ioc: + form.cores.choices = utils.get_choices( + current_app.config["VIOC_CORES_CHOICES"] ) - db.session.commit() - current_app.logger.info(f"Creation of {name} requested: task {task.id}") - flash( - f"Creation of {name} requested! Refresh the page to update the status.", - "success", + form.memory.choices = utils.get_choices( + current_app.config["VIOC_MEMORY_CHOICES"] ) - return redirect(url_for("task.view_task", id_=task.id)) + else: + form = None + if form is not None and form.validate_on_submit(): + if host.device_type.name == "Network": + if not current_user.is_admin: + flash( + f"Only admin users are allowed to generate a ZTP configuration!", + "info", + ) + return redirect(url_for("network.view_host", name=name)) + else: + task = tasks.trigger_ztp_configuration(host) + db.session.commit() + current_app.logger.info( + f"Generation of {name} ZTP configuration requested: task {task.id}" + ) + flash( + f"Generation of {name} ZTP configuration requested! Refresh the page to update the status.", + "success", + ) + return redirect(url_for("task.view_task", id_=task.id)) + else: + if not current_user.is_admin: + flash(f"Only admin users are allowed to create a VM!", "info") + return redirect(url_for("network.view_host", name=name)) + else: + interface = host.interfaces[0] + task = tasks.trigger_vm_creation( + name, interface, int(form.memory.data) * 1000, form.cores.data + ) + db.session.commit() + current_app.logger.info(f"Creation of {name} requested: task {task.id}") + flash( + f"Creation of {name} requested! Refresh the page to update the status.", + "success", + ) + return redirect(url_for("task.view_task", id_=task.id)) return render_template("network/view_host.html", host=host, form=form) diff --git a/app/settings.py b/app/settings.py index 455b247..5b9c946 100644 --- a/app/settings.py +++ b/app/settings.py @@ -75,6 +75,7 @@ AWX_URL = "https://torn.tn.esss.lu.se" AWX_CORE_SERVICES_UPDATE = "ics-ans-core @ DHCP test" AWX_CREATE_VM = "ics-ans-deploy-proxmox-vm" AWX_CREATE_VIOC = "ics-ans-deploy-vioc" +AWX_ZTP_CONFIGURATION = "ics-ans-ztp" AWX_JOB_ENABLED = False AWX_VM_CREATION_ENABLED = False diff --git a/app/tasks.py b/app/tasks.py index 97d938a..3015ff2 100644 --- a/app/tasks.py +++ b/app/tasks.py @@ -118,6 +118,29 @@ def trigger_vm_creation(name, interface, memory, cores): return task +def trigger_ztp_configuration(host): + """Trigger a job to generate a switch ZTP configuration""" + extra_vars = [ + f"ztp_host={host.name}", + f"ztp_ip={host.main_interface.ip}", + f"ztp_mac={host.main_interface.mac}", + f"ztp_model={host.model}", + ] + job_template = current_app.config["AWX_ZTP_CONFIGURATION"] + current_app.logger.info( + f"Launch new job to generate ZTP configuration for {host.name} device: {job_template} with {extra_vars}" + ) + user = utils.cse_current_user() + task = user.launch_task( + "trigger_ztp_configuration", + func="launch_job_template", + job_template=job_template, + extra_vars=extra_vars, + timeout=500, + ) + return task + + def launch_job_template(job_template, **kwargs): rq_job = get_current_job() if job_template in ( diff --git a/app/templates/network/view_host.html b/app/templates/network/view_host.html index 7eef111..92537b6 100644 --- a/app/templates/network/view_host.html +++ b/app/templates/network/view_host.html @@ -50,19 +50,26 @@ </dl> </div> {% if host.device_type.name.startswith('Virtual') and current_user.is_admin %} - {% if host.is_ioc %} - {% set vm_type = 'Virtual IOC' %} - {% else %} - {% set vm_type = 'VM' %} - {% endif %} - <div class="col-sm-3"> - <form id="createVMForm" method="POST"> - {{ form.hidden_tag() }} - {{ render_field(form.cores, label_size='6', input_size='6') }} - {{ render_field(form.memory, label_size='6', input_size='6') }} - {{ submit_button_with_confirmation('Create ' + vm_type, 'Do you really want to create the ' + vm_type + ' ' + host.name + '?') }} - </form> - </div> + {% if host.is_ioc %} + {% set vm_type = 'Virtual IOC' %} + {% else %} + {% set vm_type = 'VM' %} + {% endif %} + <div class="col-sm-3"> + <form id="createVMForm" method="POST"> + {{ form.hidden_tag() }} + {{ render_field(form.cores, label_size='6', input_size='6') }} + {{ render_field(form.memory, label_size='6', input_size='6') }} + {{ submit_button_with_confirmation('Create ' + vm_type, 'Do you really want to create the ' + vm_type + ' ' + host.name + '?') }} + </form> + </div> + {% elif host.device_type.name == 'Network' and host.model and current_user.is_admin %} + <div class="col-sm-3"> + <form id="generateZTPForm" method="POST"> + {{ form.hidden_tag() }} + {{ submit_button_with_confirmation('Generate ZTP configuration', 'Do you really want to generate the ZTP configuration for ' + host.name + '?') }} + </form> + </div> {% endif %} </div> <h3>Interfaces</h3> -- GitLab