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-web-header = Web
zone-content-section-mail-header = E-mail zone-content-section-mail-header = E-mail
zone-content-section-services-header = Services
zone-content-section-general-header = General zone-content-section-general-header = General
zone-content-record-type-address = zone-content-record-type-address =
.type-name = Addresses .type-name = IP addresses
zone-content-record-type-mailserver = zone-content-record-type-mailserver =
.type-name = E-mail servers .type-name = E-mail servers
@ -22,7 +23,6 @@ zone-content-record-type-nameserver =
zone-content-record-type-service = zone-content-record-type-service =
.type-name = Services .type-name = Services
.data-address = Address: { $address }
.data-priority = Priority: { $priority } .data-priority = Priority: { $priority }
.data-weight = Weight: { $weight } .data-weight = Weight: { $weight }

View file

@ -8,10 +8,11 @@ zone-content-aliases-header = Alias
zone-content-section-web-header = Web zone-content-section-web-header = Web
zone-content-section-mail-header = Courriel zone-content-section-mail-header = Courriel
zone-content-section-services-header = Services
zone-content-section-general-header = Général zone-content-section-general-header = Général
zone-content-record-type-address = zone-content-record-type-address =
.type-name = Adresses .type-name = Adresses IP
zone-content-record-type-mailserver = zone-content-record-type-mailserver =
.type-name = Serveurs de courriel .type-name = Serveurs de courriel
@ -22,7 +23,6 @@ zone-content-record-type-nameserver =
zone-content-record-type-service = zone-content-record-type-service =
.type-name = Services .type-name = Services
.data-address = Adresse : { $address }
.data-priority = Priorité : { $priority } .data-priority = Priorité : { $priority }
.data-weight = Poids : { $weight } .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}; use serde::{Deserialize, Serialize, Serializer, ser::SerializeStruct};
@ -157,15 +157,25 @@ impl WebConfiguration {
pub struct FriendlyRecordSetGroup { pub struct FriendlyRecordSetGroup {
owner: String, owner: String,
general_records: Vec<FriendlyRecordSet<FriendlyRData>>, general_records: Vec<FriendlyRecordSet<FriendlyRData>>,
#[serde(serialize_with = "as_vector")]
services: HashMap<ServiceType, FriendlyRecordSet<Service>>,
mail: Option<MailConfiguration>, mail: Option<MailConfiguration>,
web: Option<WebConfiguration>, 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 { impl FriendlyRecordSetGroup {
pub fn new(owner: String) -> Self { pub fn new(owner: String) -> Self {
FriendlyRecordSetGroup { FriendlyRecordSetGroup {
owner, owner,
general_records: Vec::new(), general_records: Vec::new(),
services: HashMap::new(),
mail: None, mail: None,
web: None, web: None,
} }
@ -237,6 +247,11 @@ impl From<internal::RecordList> for FriendlyRecords {
mail.spf = Some(FriendlyRecord::new(ttl, spf)); 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(_) => {}, FriendlyRData::Alias(_) => {},
data => { data => {
// TODO: NS -> Skip if NS for zone (authority), create Delegation section with glue + DS for others (how to check if record is glue?) // 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)] #[derive(Debug, Deserialize, Serialize)]
pub struct Service { pub struct Service {
pub service_type: ServiceType, pub service_type: ServiceType,
pub service_name: Option<String>,
pub service_protocol: Option<String>,
pub port: i64, pub port: i64,
pub weight: i64, pub weight: i64,
pub priority: i64, pub priority: i64,
pub server: String, pub server: String,
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize, Hash, Eq, PartialEq, Clone)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase", tag = "service_type")]
pub enum ServiceType { pub enum ServiceType {
Other, Other { protocol: String, name: String },
}
impl HasRType for Service {
fn rtype(&self) -> FriendlyRType {
FriendlyRType::Service
}
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]

View file

@ -148,9 +148,10 @@ impl Srv {
let protocol = labels[1]. strip_prefix('_'); let protocol = labels[1]. strip_prefix('_');
if let (Some(service_name), Some(protocol)) = (service_name, protocol) { if let (Some(service_name), Some(protocol)) = (service_name, protocol) {
Some((labels[2].to_string(), friendly::FriendlyRData::Service(friendly::Service { Some((labels[2].to_string(), friendly::FriendlyRData::Service(friendly::Service {
service_type: friendly::ServiceType::Other, service_type: friendly::ServiceType::Other {
service_name: Some(service_name.into()), name: service_name.into(),
service_protocol: Some(protocol.into()), protocol: protocol.into()
},
port: self.port.into(), port: self.port.into(),
weight: self.weight.into(), weight: self.weight.into(),
priority: self.priority.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"> <li class="rrset">
<div class="rtype"> <div class="rtype">
{% 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) }} {{ tr(msg="zone-content-record-type-" ~ rtype, attr="type-name", lang=lang) }}
{% endif %}
<div class="action"> <div class="action">
<a class="button icon" href="#"> <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"> <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" %} {% elif rtype == "service" %}
<div class="rdata-main"> <div class="rdata-main">
<span class="pill"> <span class="pill">
{% if data.service_type == "other" %} {{ data.server ~ ":" ~ data.port }}
{{ 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) }}
</span> </span>
</div> </div>
<div class="rdata-complementary"> <div class="rdata-complementary">

View file

@ -64,6 +64,21 @@
</ul> </ul>
{% endif %} {% 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 %} {% if group.general_records %}
<h4>{{ tr(msg="zone-content-section-general-header", lang=lang) }}</h4> <h4>{{ tr(msg="zone-content-section-general-header", lang=lang) }}</h4>
<ul> <ul>