mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 11:46:49 +00:00
As the storage pages; reviewed with Codex. - The list is a card per network: its name with Active or Stopped and Autostart badges, its type (network_mode: Isolated, NAT, Routed, Open, Bridge, Macvtap, SR-IOV), its device, and each address with its DHCP range; a bridge or macvtap network's addresses come from the outside network. - A network's page: its heading starts or stops it, the menu sets autostart and deletes a stopped one. A Network card tells its state, type, bridge or interface, MAC and what the type does; a card per address (every <ip>, each with its DHCP range dialog, which libvirt takes on a stopped network); its fixed addresses of every subnet in one table, searched, each with Edit and Delete, one dialog adding and editing them; the VMs whose definition names it, connected or configured, linked (wvmNetwork.get_vms, one domain listing, a VM undefined meanwhile left out); its bandwidth limits where libvirt sets them (not on macvtap or SR-IOV networks), in KiB/s, from the saved definition with a note that a running network takes them when restarted; its XML in an accordion. The page reads the running and the saved definition once each, and only to render itself: its actions, which all redirect, read nothing of it first. - The New network dialog is one form, as the New pool one: the type as radio cards (the radio_card.html include, now shared by both), the chosen type's fields only, IPv6 with its box, a bridge or interface suggested from the host's (get_host_interfaces, not the bridges libvirt made for its own networks); a refused network or one libvirt refuses opens the dialog again with what was entered, the reasons beside the fields and focus on the first. - What the New pool and New network dialogs share is one script, static/js/choice_dialog.js: the radio cards show their fieldsets (data-kinds) and a refused form opens again focused on its first refused field; each dialog keeps only its own changes. - The fixed-address dialogs per family go to the page's own dialog.
73 lines
4.2 KiB
HTML
73 lines
4.2 KiB
HTML
{% extends "base.html" %}
|
||
{% load i18n %}
|
||
{% load bootstrap_icons %}
|
||
|
||
{% block title %}{% trans "Networks" %} - {{ compute.name }}{% endblock %}
|
||
|
||
{% block page_heading %}{{ compute.name }} - {% trans "Networks" %}{% endblock page_heading %}
|
||
|
||
{% block page_heading_extra %}{% include 'create_net_block.html' %}{% endblock page_heading_extra %}
|
||
|
||
{% block content %}
|
||
{% include "computes/host_nav.html" with section="networks" %}
|
||
|
||
{% if not networks %}
|
||
<div class="alert alert-warning shadow-sm">
|
||
{% bs_icon 'exclamation-triangle' %} {% trans "This host has no networks." %}
|
||
</div>
|
||
{% else %}
|
||
{# a card per network, as the host Overview's Hardware and Software cards #}
|
||
<div class="row row-cols-1 row-cols-md-2 g-3 mb-4">
|
||
{% for net in networks %}
|
||
<div class="col">
|
||
<div class="card h-100">
|
||
<div class="card-header d-flex flex-wrap align-items-center gap-2">
|
||
<a class="fw-semibold me-auto text-break" href="{% url 'network' compute.id net.name %}">{{ net.name }}</a>
|
||
{% if net.status %}
|
||
<span class="badge text-bg-success">{% trans "Active" %}</span>
|
||
{% else %}
|
||
<span class="badge text-bg-secondary">{% trans "Stopped" %}</span>
|
||
{% endif %}
|
||
{% if net.autostart %}<span class="badge text-bg-light border">{% trans "Autostart" %}</span>{% endif %}
|
||
</div>
|
||
<ul class="list-group list-group-flush flex-grow-1">
|
||
<li class="list-group-item d-flex justify-content-between align-items-baseline gap-3">
|
||
<span class="text-body-secondary">{% trans "Type" %}</span>
|
||
<span class="badge text-bg-light border">{{ net.mode_label }}</span>
|
||
</li>
|
||
<li class="list-group-item d-flex justify-content-between align-items-baseline gap-3">
|
||
<span class="text-body-secondary">{% trans "Device" %}</span>
|
||
<span class="font-monospace text-break text-end">{{ net.device|default:"–" }}</span>
|
||
</li>
|
||
{% if net.external %}
|
||
<li class="list-group-item d-flex justify-content-between align-items-baseline gap-3">
|
||
<span class="text-body-secondary">{% trans "Addresses" %}</span>
|
||
<span class="text-body-secondary text-end">{% trans "from the outside network" %}</span>
|
||
</li>
|
||
{% else %}
|
||
{% for ip in net.ips %}
|
||
<li class="list-group-item d-flex justify-content-between align-items-baseline gap-3">
|
||
<span class="text-body-secondary">{% if ip.family == "ipv6" %}IPv6{% else %}IPv4{% endif %}</span>
|
||
<span class="text-end">
|
||
<span class="font-monospace text-break">{{ ip.subnet|default:ip.address }}</span>
|
||
<span class="d-block small text-body-secondary">
|
||
{% if ip.range %}{% blocktrans with start=ip.range.0 end=ip.range.1 %}DHCP {{ start }} – {{ end }}{% endblocktrans %}
|
||
{% elif ip.dhcp %}{% trans "DHCP: fixed addresses only" %}
|
||
{% else %}{% trans "No DHCP" %}{% endif %}
|
||
</span>
|
||
</span>
|
||
</li>
|
||
{% empty %}
|
||
<li class="list-group-item d-flex justify-content-between align-items-baseline gap-3">
|
||
<span class="text-body-secondary">{% trans "Addresses" %}</span>
|
||
<span class="text-body-secondary text-end">{% trans "none" %}</span>
|
||
</li>
|
||
{% endfor %}
|
||
{% endif %}
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
{% endblock %}
|