diff --git a/app/models.py b/app/models.py index 0a5eed59ac93192e7a4345b52d46af35fb100ce2..69217b7892845855765b09e0302583776f123915 100644 --- a/app/models.py +++ b/app/models.py @@ -899,7 +899,11 @@ class Host(CreatedMixin, db.Model): ) ansible_vars = db.Column(postgresql.JSONB) - interfaces = db.relationship("Interface", backref="host") + # Set cascade to all (to add delete) and delete-orphan to delete all interfaces + # when deleting a host + interfaces = db.relationship( + "Interface", backref="host", cascade="all, delete-orphan" + ) items = db.relationship("Item", backref="host") ansible_groups = db.relationship( "AnsibleGroup", diff --git a/app/network/views.py b/app/network/views.py index 67c99db24cb00535bf831e76958853efe8f04d00..26e691e3201f129f7d547b57575f23ac08af586d 100644 --- a/app/network/views.py +++ b/app/network/views.py @@ -107,6 +107,19 @@ def create_host(): return render_template("network/create_host.html", form=form) +@bp.route("/hosts/delete", methods=["POST"]) +@login_groups_accepted("admin") +def delete_host(): + host = models.Host.query.get_or_404(request.form["host_id"]) + # Deleting the host will also delete all + # associated interfaces due to the cascade delete option + # defined on the model + db.session.delete(host) + db.session.commit() + flash(f"Host {host.name} has been deleted", "success") + return redirect(url_for("network.list_hosts")) + + @bp.route("/hosts/view/<name>", methods=("GET", "POST")) @login_required def view_host(name): diff --git a/app/templates/network/view_host.html b/app/templates/network/view_host.html index 908d2af140c50c0ad86bab085349cb2613d25054..4f16c2e0d9630027ef87dfb63a0c51d55a8f1a7e 100644 --- a/app/templates/network/view_host.html +++ b/app/templates/network/view_host.html @@ -22,7 +22,22 @@ <div class="col-sm-9"> <dl class="row"> <dt class="col-sm-3">Hostname</dt> - <dd class="col-sm-9">{{ host.fqdn }}</dd> + <dd class="col-sm-9"> + <div class="row"> + <div class="col-sm-10"> + {{ host.fqdn }} + </div> + {% if current_user.is_admin %} + <div class="col-sm-2 text-right"> + <form method="POST" action="/network/hosts/delete"> + <input id="host_id" name="host_id" type="hidden" value="{{ host.id }}"> + {{ delete_button_with_confirmation("Delete host", "deleteConfirmation-%s" | format(host.id), + "Are you sure you want to delete the host %s?" | format(host.name)) }} + </form> + </div> + {% endif %} + </div> + </dd> <dt class="col-sm-3">Device Type</dt> <dd class="col-sm-9">{{ host.device_type }}</dd> {% if host.items %} diff --git a/docs/_static/network/delete_host_confirmation.png b/docs/_static/network/delete_host_confirmation.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8383deffc4e51707f7f9ec11dac1fa0cd7374f Binary files /dev/null and b/docs/_static/network/delete_host_confirmation.png differ diff --git a/docs/_static/network/view_host_delete.png b/docs/_static/network/view_host_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..04479fbf503495fafcdb018f9caf5c99b7a65816 Binary files /dev/null and b/docs/_static/network/view_host_delete.png differ diff --git a/docs/network.rst b/docs/network.rst index 71cf6c550ba24a3feb2fbc535cb4cb08505c903a..fd2ec6a34a7513ffbad3ce5059626ea24072a5fe 100644 --- a/docs/network.rst +++ b/docs/network.rst @@ -49,6 +49,23 @@ If you need more than one interface, you should go to the *Add interface* pane f .. image:: _static/add_interface.png + +Delete a host +------------- + +Note that this is restricted to admin users. +To delete a host, just click on the **trash** icon next to the hostname on the *View host* page. + +.. image:: _static/network/view_host_delete.png + +A confirmation window will be opened. You can confirm or cancel the action. + +.. image:: _static/network/delete_host_confirmation.png + +When deleting a host, all its interfaces are deleted as well. +The host is only deleted from CSEntry. Virtual machines are not automatically deleted. + + DNS and DHCP update -------------------