mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
The console page of a VM whose host does not answer said "Fail to get console. Please check the console configuration of your VM." and logged nothing. It now shows the connection error (to users who do not see the hosts, that the host cannot be reached) and logs it with the VM and host. A host's Storage, Networks, Interfaces, Filters and Secrets pages showed the connection error and also "This host has no ...". The list is None when it was not read, and the page shows only the error.
119 lines
8.2 KiB
HTML
119 lines
8.2 KiB
HTML
{% extends "base.html" %}
|
||
{% load i18n %}
|
||
{% load static %}
|
||
{% load bootstrap_icons %}
|
||
|
||
{% block title %}{% trans "Secrets" %} - {{ compute.name }}{% endblock %}
|
||
|
||
{% block page_heading %}{{ compute.name }} - {% trans "Secrets" %}{% endblock page_heading %}
|
||
|
||
{% block page_heading_extra %}{% include 'create_secret_block.html' %}{% endblock page_heading_extra %}
|
||
|
||
{% block content %}
|
||
{% include "computes/host_nav.html" with section="virtsecrets" %}
|
||
|
||
{% if secrets_all is None %}{# not read: the error above says why #}{% elif not secrets_all %}
|
||
<div class="alert alert-warning shadow-sm">
|
||
{% bs_icon 'exclamation-triangle' %} {% trans "This host has no secrets." %}
|
||
</div>
|
||
{% else %}
|
||
<div class="card mb-3">
|
||
<div class="card-header d-flex flex-wrap align-items-center gap-2">
|
||
<span class="me-auto">{% trans "Secrets" %} <span class="badge text-bg-light border">{{ secrets_all|length }}</span></span>
|
||
<input id="filter" class="form-control form-control-sm w-auto" type="search" placeholder="{% trans "Search" %}" aria-label="{% trans "Search secrets" %}">
|
||
</div>
|
||
<div class="table-responsive position-relative">
|
||
<table class="table table-hover align-middle mb-0" data-sortable>
|
||
<thead>
|
||
<tr>
|
||
<th scope="col">{% trans "Type" %}</th>
|
||
<th scope="col">{% trans "Usage" %}</th>
|
||
<th scope="col">{% trans "Kept" %}</th>
|
||
<th scope="col">{% trans "Used by" %}</th>
|
||
<th scope="col" data-sort-method="none"><span class="visually-hidden">{% trans "Actions" %}</span></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="searchable">
|
||
{% for secret in secrets_all %}
|
||
<tr data-search="{{ secret.usage_type }} {{ secret.usage }} {{ secret.uuid }}{% for vm in secret.vms %} {{ vm.name }}{% endfor %}{% for pool in secret.pools %} {{ pool }}{% endfor %}">
|
||
<td><span class="badge text-bg-light border">{{ secret.type_label }}</span></td>
|
||
<td class="text-nowrap">
|
||
<div class="font-monospace">{{ secret.usage|default:"–" }}</div>
|
||
<div class="font-monospace small text-body-secondary">{{ secret.uuid }}</div>
|
||
</td>
|
||
<td class="small text-nowrap">
|
||
{% if secret.ephemeral %}{% trans "In memory" %}{% else %}{% trans "On disk" %}{% endif %}{% if secret.private %}, {% trans "private" %}{% endif %}
|
||
</td>
|
||
<td class="small text-nowrap">
|
||
{% for vm in secret.vms %}
|
||
<div>
|
||
{% bs_icon 'pc-display' %}
|
||
{% if vm.id %}
|
||
<a href="{% url 'instances:instance' vm.id %}">{{ vm.name }}</a>
|
||
{% else %}
|
||
{{ vm.name }}
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
{% for pool in secret.pools %}
|
||
<div>{% bs_icon 'hdd-stack' %} <a href="{% url 'storage' compute.id pool %}">{{ pool }}</a></div>
|
||
{% endfor %}
|
||
{% if not secret.vms and not secret.pools %}–{% endif %}
|
||
</td>
|
||
<td class="text-end">
|
||
<div class="btn-group">
|
||
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="dropdown" aria-expanded="false"
|
||
data-bs-popper-config='{"strategy": "fixed"}' aria-label="{% blocktrans with usage=secret.usage|default:secret.uuid %}Actions for secret {{ usage }}{% endblocktrans %}">{% bs_icon 'three-dots' %}</button>
|
||
<ul class="dropdown-menu dropdown-menu-end shadow">
|
||
<li><button type="button" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#SetSecretValue"
|
||
data-uuid="{{ secret.uuid }}" data-usage="{{ secret.usage|default:secret.uuid }}" data-type="{{ secret.usage_type }}">{% bs_icon 'key' %} {% trans "Set value" %}</button></li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li><form method="post">{% csrf_token %}
|
||
<input type="hidden" name="uuid" value="{{ secret.uuid }}">
|
||
{# a secret in use is not deleted: the VM or pool using it would not start #}
|
||
<button type="submit" class="dropdown-item text-danger" name="delete"{% if secret.vms or secret.pools %} disabled{% endif %}
|
||
data-confirm="{% blocktrans with usage=secret.usage|default:secret.uuid %}Delete secret {{ usage }}? Its stored value will be lost. No current or saved definition of a VM or pool names it; snapshots, LUKS volumes and qemu.conf's TLS settings are not checked.{% endblocktrans %}">{% bs_icon 'trash' %} {% if secret.vms or secret.pools %}{% trans "Delete (in use)" %}{% else %}{% trans "Delete secret" %}{% endif %}</button>
|
||
</form></li>
|
||
</ul>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div role="status">
|
||
<div id="no-match" class="text-center text-body-secondary py-3" hidden>{% trans "No secret matches the search." %}</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# one dialog for every secret's value: its row's Set value fills in the secret #}
|
||
<div class="modal fade" id="SetSecretValue" tabindex="-1" aria-labelledby="SetSecretValueLabel" aria-hidden="true">
|
||
<div class="modal-dialog">
|
||
<form method="post" class="modal-content">{% csrf_token %}
|
||
<input type="hidden" name="uuid">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title text-break" id="SetSecretValueLabel">{% trans "Set the value of" %} <span class="font-monospace" id="value_usage"></span></h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans "Close" %}"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<label for="set_value" class="form-label" id="set_value_label">{% trans "Value" %}</label>
|
||
<input type="password" id="set_value" name="value" class="form-control" autocomplete="new-password" required aria-describedby="set_value_help set_value_note">
|
||
<div class="form-text" id="set_value_help"></div>
|
||
<div class="form-text" id="set_value_note" hidden>{% trans "It replaces the old value at once; what a passphrase encrypted is not encrypted anew." %}</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
|
||
<button type="submit" class="btn btn-primary" name="set_value">{% trans "Set value" %}</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endblock %}
|
||
|
||
{% block script %}
|
||
{% if secrets_all %}<script src="{% static 'js/table_filter.js' %}"></script>{% endif %}
|
||
{{ usage_texts|json_script:"usage-texts" }}
|
||
<script src="{% static 'js/secrets_page.js' %}"></script>
|
||
{% endblock %}
|