feat: DNS_SERVER env var — pre-fills discovery UI, optional for scan

- DNS_SERVER env var configures the default DNS server for PTR lookups
- GET /api/discovery/config exposes it to the frontend
- DiscoveryModal fetches it on mount and pre-fills the field (editable)
- dns_server is now optional in ScanRequest (default empty string)
- PTR lookup is skipped when dns_server is empty — scan still proceeds
- Validator only runs when dns_server is non-empty
- .env.example, docker-compose.yml, READMEs (fr/en/es) updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 12:22:05 +02:00
parent c8607831a4
commit 806fe1caec
9 changed files with 43 additions and 16 deletions
+3 -2
View File
@@ -46,6 +46,7 @@ export const devicesApi = {
}
export const discoveryApi = {
scan: (data) => http.post('/discovery/scan', data),
ping: (ips) => http.post('/discovery/ping', { ips }),
config: () => http.get('/discovery/config'),
scan: (data) => http.post('/discovery/scan', data),
ping: (ips) => http.post('/discovery/ping', { ips }),
}
+8 -5
View File
@@ -173,7 +173,7 @@
</template>
<script setup>
import { ref, computed } from 'vue'
import { ref, computed, onMounted } from 'vue'
import { devicesApi, discoveryApi } from '../api.js'
import { t } from '../i18n.js'
@@ -194,6 +194,13 @@ const configError = ref('')
const importError = ref('')
const importing = ref(false)
onMounted(async () => {
try {
const resp = await discoveryApi.config()
dnsServer.value = resp.data.dns_server || ''
} catch { /* ignore — field stays empty */ }
})
const scanableVlans = computed(() => props.vlans.filter(v => v.cidr))
const existingIps = computed(() => {
@@ -246,10 +253,6 @@ function toggleAll(e) {
async function startScan() {
configError.value = ''
if (!dnsServer.value.trim()) {
configError.value = t('dnsRequired')
return
}
if (selectedVlanIds.value.length === 0) {
configError.value = t('selectVlan')
return
+3 -3
View File
@@ -118,7 +118,7 @@ const LANGS = {
// DiscoveryModal
autoDiscovery: 'Découverte automatique',
dnsServer: 'Serveur DNS',
dnsHint: 'Le reverse DNS sera interrogé sur ce serveur pour résoudre les noms.',
dnsHint: 'Optionnel. Si renseigné, le reverse DNS (PTR) sera interrogé pour résoudre les noms d'hôtes. Configurez la valeur par défaut via DNS_SERVER dans .env.',
vlansToScan: 'VLANs à scanner',
vlansHint: 'Seuls les VLANs avec un sous-réseau CIDR configuré peuvent être scannés.',
noCidrWarning: "Aucun VLAN n'a de CIDR configuré. Renseignez-les dans l'onglet VLANs.",
@@ -277,7 +277,7 @@ const LANGS = {
subnetPlaceholder: 'e.g. 192.168.10.0/24',
autoDiscovery: 'Auto discovery',
dnsServer: 'DNS server',
dnsHint: 'Reverse DNS will be queried on this server to resolve hostnames.',
dnsHint: 'Optional. If set, reverse DNS (PTR) will be queried to resolve hostnames. Set the default via DNS_SERVER in .env.',
vlansToScan: 'VLANs to scan',
vlansHint: 'Only VLANs with a configured CIDR subnet can be scanned.',
noCidrWarning: 'No VLAN has a CIDR configured. Set them in the Networks tab.',
@@ -435,7 +435,7 @@ const LANGS = {
subnetPlaceholder: 'ej: 192.168.10.0/24',
autoDiscovery: 'Descubrimiento automático',
dnsServer: 'Servidor DNS',
dnsHint: 'El DNS inverso será consultado en este servidor para resolver nombres.',
dnsHint: 'Opcional. Si se indica, se consultará el DNS inverso (PTR) para resolver nombres de host. Configure el valor por defecto con DNS_SERVER en .env.',
vlansToScan: 'VLANs a escanear',
vlansHint: 'Solo los VLANs con subred CIDR configurada pueden escanearse.',
noCidrWarning: 'Ninguna VLAN tiene CIDR configurado. Configúrelo en la pestaña Redes.',