make services a sections

This commit is contained in:
Hannaeko 2025-05-09 16:57:06 +02:00
parent 06fddae344
commit 91bffe153a
6 changed files with 59 additions and 27 deletions

View file

@ -8,10 +8,11 @@ zone-content-aliases-header = Aliases
zone-content-section-web-header = Web
zone-content-section-mail-header = E-mail
zone-content-section-services-header = Services
zone-content-section-general-header = General
zone-content-record-type-address =
.type-name = Addresses
.type-name = IP addresses
zone-content-record-type-mailserver =
.type-name = E-mail servers
@ -22,7 +23,6 @@ zone-content-record-type-nameserver =
zone-content-record-type-service =
.type-name = Services
.data-address = Address: { $address }
.data-priority = Priority: { $priority }
.data-weight = Weight: { $weight }

View file

@ -8,10 +8,11 @@ zone-content-aliases-header = Alias
zone-content-section-web-header = Web
zone-content-section-mail-header = Courriel
zone-content-section-services-header = Services
zone-content-section-general-header = Général
zone-content-record-type-address =
.type-name = Adresses
.type-name = Adresses IP
zone-content-record-type-mailserver =
.type-name = Serveurs de courriel
@ -22,7 +23,6 @@ zone-content-record-type-nameserver =
zone-content-record-type-service =
.type-name = Services
.data-address = Adresse : { $address }
.data-priority = Priorité : { $priority }
.data-weight = Poids : { $weight }

View file

@ -1,4 +1,4 @@
use std::fmt;
use std::{collections::HashMap, fmt};
use serde::{Deserialize, Serialize, Serializer, ser::SerializeStruct};
@ -157,15 +157,25 @@ impl WebConfiguration {
pub struct FriendlyRecordSetGroup {
owner: String,
general_records: Vec<FriendlyRecordSet<FriendlyRData>>,
#[serde(serialize_with = "as_vector")]
services: HashMap<ServiceType, FriendlyRecordSet<Service>>,
mail: Option<MailConfiguration>,
web: Option<WebConfiguration>,
}
fn as_vector<S>(services: &HashMap<ServiceType, FriendlyRecordSet<Service>>, ser: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let container: Vec<_> = services.iter().collect();
serde::Serialize::serialize(&container, ser)
}
impl FriendlyRecordSetGroup {
pub fn new(owner: String) -> Self {
FriendlyRecordSetGroup {
owner,
general_records: Vec::new(),
services: HashMap::new(),
mail: None,
web: None,
}
@ -237,6 +247,11 @@ impl From<internal::RecordList> for FriendlyRecords {
mail.spf = Some(FriendlyRecord::new(ttl, spf));
},
FriendlyRData::Service(service) => {
let services = current_group.services.entry(service.service_type.clone()).or_insert(FriendlyRecordSet::new(ttl));
services.data.push(service)
}
FriendlyRData::Alias(_) => {},
data => {
// TODO: NS -> Skip if NS for zone (authority), create Delegation section with glue + DS for others (how to check if record is glue?)
@ -278,18 +293,22 @@ impl HasRType for Address {
#[derive(Debug, Deserialize, Serialize)]
pub struct Service {
pub service_type: ServiceType,
pub service_name: Option<String>,
pub service_protocol: Option<String>,
pub port: i64,
pub weight: i64,
pub priority: i64,
pub server: String,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
#[derive(Debug, Deserialize, Serialize, Hash, Eq, PartialEq, Clone)]
#[serde(rename_all = "lowercase", tag = "service_type")]
pub enum ServiceType {
Other,
Other { protocol: String, name: String },
}
impl HasRType for Service {
fn rtype(&self) -> FriendlyRType {
FriendlyRType::Service
}
}
#[derive(Debug, Deserialize, Serialize)]

View file

@ -148,9 +148,10 @@ impl Srv {
let protocol = labels[1]. strip_prefix('_');
if let (Some(service_name), Some(protocol)) = (service_name, protocol) {
Some((labels[2].to_string(), friendly::FriendlyRData::Service(friendly::Service {
service_type: friendly::ServiceType::Other,
service_name: Some(service_name.into()),
service_protocol: Some(protocol.into()),
service_type: friendly::ServiceType::Other {
name: service_name.into(),
protocol: protocol.into()
},
port: self.port.into(),
weight: self.weight.into(),
priority: self.priority.into(),

View file

@ -1,7 +1,15 @@
{% macro rrset(rtype, ttl, data, zone, lang) %}
{% macro rrset(rtype, ttl, data, zone, lang, service_type="") %}
<li class="rrset">
<div class="rtype">
{{ tr(msg="zone-content-record-type-" ~ rtype, attr="type-name", lang=lang) }}
{% if rtype == "service" %}
{% if service_type.service_type == "other" %}
{{ service_type.name }}/{{ service_type.protocol }}
{% else %}
{{ service_type.service_type }}
{% endif %}
{% else %}
{{ tr(msg="zone-content-record-type-" ~ rtype, attr="type-name", lang=lang) }}
{% endif %}
<div class="action">
<a class="button icon" href="#">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
@ -45,18 +53,7 @@
{% elif rtype == "service" %}
<div class="rdata-main">
<span class="pill">
{% if data.service_type == "other" %}
{{ data.service_name }}/{{ data.service_protocol }}
{% else %}
{{ data.service_type }}
{% endif %}
</span>
<span class="pill">
{{ tr(
msg="zone-content-record-type-service",
attr="data-address",
address=data.server ~ ":" ~ data.port,
lang=lang) }}
{{ data.server ~ ":" ~ data.port }}
</span>
</div>
<div class="rdata-complementary">

View file

@ -64,6 +64,21 @@
</ul>
{% endif %}
{% if group.services %}
<h4>{{ tr(msg="zone-content-section-services-header", lang=lang) }}</h4>
<ul>
{% for service in group.services %}
{{ rrset::rrset(
rtype=service[1].rtype,
ttl=service[1].ttl,
data=service[1].data,
zone=current_zone,
lang=lang,
service_type=service[0]) }}
{% endfor %}
</ul>
{% endif %}
{% if group.general_records %}
<h4>{{ tr(msg="zone-content-section-general-header", lang=lang) }}</h4>
<ul>