Do not write path with "/" If the script can be run on also on v6
"/ip/dns/static/find" is incopmpatible on v6, but "/ip dns static find" is compatible with both v6 and v7
Do not mix "styles", or use "/" or not use:
:foreach entry in [/ip/dns/static/find where comment=$Magic] do={
:local fqdn [/ip dns static get value-name=name $entry]
If possible, make easier the scripting, this is also more readable
How to include hostnames with _ character? I’ve always used this font with no problems and this script is great if it would include these names
# syncdns version: 1.0.0
#
# A RouterOS script to synchronise DNS with DHCP leases.
# This may be run regularly or whenever a DHCP event occurs.
#
# Copyright 2022 by Michael Paddon.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# default domain for DNS records
:global DefaultDomain "localdomain"
# TTL for DNS records
:global DnsTtl 5m
# magic comment for DNS records
:global Magic "automatic-from-dhcp"
# return the domain associated with an address
:global GetDomain do={
:global DefaultDomain
:local ipaddr [:toip $1]
/ip dhcp-server network
:foreach network in [find] do={
:local netblock [get value-name=address $network]
:if ($ipaddr in $netblock) do={
:return [get value-name=domain $network]
}
}
:return $DefaultDomain
}
# is a string a valid DNS name?
:global IsValidName do={
:local string [:tostr $1]
:return ($string ~ "^[A-Za-z]([A-Za-z0-9-_]{0,61}[A-Za-z0-9])?\$")
}
# return an array of fqdn=ipaddr items
:global GetFqdns do={
:global GetDomain
:global IsValidName
/ip dhcp-server lease
:local fqdns [:toarray ""]
:foreach lease in [find] do={
:local hostname [get value-name=host-name $lease]
:if ([$IsValidName $hostname]) do={
:local ipaddr [get value-name=address $lease]
:local domain [$GetDomain $ipaddr]
:local fqdn "$hostname.$domain"
:if ([:len ($fqdns->$fqdn)] = 0) do={
:set ($fqdns->$fqdn) $ipaddr
}
}
}
:return $fqdns
}
# update a DNS record, returning true if a change was made
:global Update do={
:global DnsTtl
:global Magic
:local fqdn [:tostr $1]
:local ipaddr [:toip $2]
# correct record already present?
/ip dns static
:if ([:len [find where name=$fqdn address=$ipaddr ttl=$DnsTtl comment=$Magic]] > 0) do={
:return false
}
# if record exists it must be updated
:local exists [find where name=$fqdn comment=$Magic]
:if ([:len $exists] > 0) do={
:log info "syncdns: update $fqdn -> $ipaddr"
set address=$ipaddr ttl=$DnsTtl $exists
:return true
}
# if no record of that name exists at all, create record
# note: a manually created record may exist which MUST NOT be touched
:if ([:len [find where name=$fqdn]] = 0) do={
:log info "syncdns: add $fqdn -> $ipaddr"
add name=$fqdn address=$ipaddr ttl=$DnsTtl comment=$Magic
:return true
}
:return false
}
# synchronize DNS
:global SyncDns do={
:global GetFqdns
:global Magic
:global Update
# update dns records
:local fqdns [$GetFqdns]
:foreach fqdn,ipaddr in=$fqdns do={
[$Update $fqdn $ipaddr]
}
# remove obsolete dns records
/ip dns static
:foreach entry in [find where comment=$Magic] do={
:local fqdn [get value-name=name $entry]
:if ([:len ($fqdns->$fqdn)] = 0) do={
:log info "syncdns: remove $fqdn"
remove $entry
}
}
}
:log info "syncdns: synchronize"
[$SyncDns]
:local HostName [/ip dhcp-server lease get number=[find where mac-address=$leaseActMAC] host-name]
When already exist on purpose the variable lease-hostname (but probably you are unable to use it for next point)
Just use $“lease-hostname”
And also the “debug” part is wrong, because both lease-hostname and lease-options must be surrounded by quotes or do not work correctly and broken the script
:log info message=("lease-hostname = " . $lease-hostname)
:log info message=("lease-options = " . $lease-options)
correct are $“lease-hostname” and $“lease-options”
Instead, regarding the fact that it is more logical to be done by the DHCP script, instead of the scheduler, it is more logical and correct.