WIP(osal.coredns): add example for coredns usage

- added openssl and iproute2 installation to install_v.sh since they're
  needed in coredns installation and usage.
- fixed bug in coredns build process.
- fixed bug in getting own public ip.
- fixed bugs in json encoding dns records before pushing to redis
This commit is contained in:
2025-02-10 17:07:49 +00:00
parent 86e3fdb910
commit 3117d288b1
5 changed files with 57 additions and 31 deletions

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
#!/usr/bin/env -S v -n -w -cg -d use_openssl -enable-globals run
import freeflowuniverse.herolib.installers.infra.coredns as coredns_installer
import freeflowuniverse.herolib.osal.coredns
@@ -11,10 +11,36 @@ installer.start()!
// TODO: create heroscript and run it to add dns records
mut script := '
dns.a_record
name: "a_rec1"
!!dns.a_record
name: "host1"
ip: "1.1.1.1"
'
!!dns.aaaa_record
name: "host2"
ip: "2001:db8::1"
ttl: 300
!!dns.mx_record
host: "mail.heroexample.com"
preference: 10
ttl: 300
!!dns.txt_record
text: "v=spf1 mx ~all"
ttl: 300
!!dns.srv_record
target: "sip.heroexample.com"
port: 5060
priority: 10
weight: 100
ttl: 300
!!dns.ns_record
host: "ns1.heroexample.com"
ttl: 300
'
mut plbook := playbook.new(text: script)!
coredns.play_dns(mut plbook)!
rec := coredns.play_dns(mut plbook)!
rec.set('heroexample.com')!

View File

@@ -181,7 +181,7 @@ function os_update {
fi
#apt install apt-transport-https ca-certificates curl software-properties-common -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" --force-yes
package_install "apt-transport-https ca-certificates curl wget software-properties-common tmux"
package_install "rclone rsync mc redis-server screen net-tools git dnsutils htop ca-certificates screen lsb-release binutils pkg-config"
package_install "rclone rsync mc redis-server screen net-tools git dnsutils htop ca-certificates screen lsb-release binutils pkg-config libssl-dev iproute2"
elif [[ "${OSNAME}" == "darwin"* ]]; then
if command -v brew >/dev/null 2>&1; then

View File

@@ -132,10 +132,7 @@ fn build() ! {
mut path := pathlib.get_file(path: '${gitpath}/plugin.cfg', create: true)!
path.write(pluginsfile)!
cmd := '
cd ${gitpath}
make
'
cmd := 'bash -c "cd ${gitpath} && make"'
osal.execute_stdout(cmd)!
// now copy to the default bin path

View File

@@ -1,6 +1,5 @@
module coredns
import json
import freeflowuniverse.herolib.core.redisclient
import x.json2
@@ -85,13 +84,14 @@ pub fn (mut rs DNSRecordSet) set_soa(args SOARecord) {
// populate_redis populates Redis with the DNS records
// domain e.g. example.com. (not sure the . is at end)
pub fn (rs DNSRecordSet) set(domain string) ! {
pub fn (rs DNSRecordSet) set(domain_ string) ! {
domain := '_dns:${domain_}'
mut redis := rs.redis or { redisclient.core_get()! }
println('setting: ${rs}')
// Store SRV records
for srv in rs.srv {
key := '_ssh._tcp.host1'
value := json.encode({
value := json2.encode({
'srv': {
'ttl': '${srv.ttl}'
'target': '${srv.target}'
@@ -119,23 +119,26 @@ pub fn (rs DNSRecordSet) set(domain string) ! {
'ttl': rs.mx[0].ttl
}
}
redis.hset(domain, '*', json.encode(records))!
redis.hset(domain, '*', json2.encode(records))!
}
// Store A records
for a in rs.a {
value := json.encode({
value := json2.encode({
'a': {
'ip4': a.ip
'ttl': '${a.ttl}'
}
})
println('redis: ${redis}')
println('domain: ${domain}')
println('value: ${value}')
redis.hset(domain, a.name, value)!
}
// Store AAAA records
for aaaa in rs.aaaa {
value := json.encode({
value := json2.encode({
'aaaa': {
'ip6': aaaa.ip
'ttl': '${aaaa.ttl}'
@@ -146,14 +149,14 @@ pub fn (rs DNSRecordSet) set(domain string) ! {
// Store NS records
if rs.ns.len > 0 {
mut ns_records := []map[string]string{}
mut ns_records := []json2.Any{}
for ns in rs.ns {
ns_records << {
ns_records << json2.raw_decode(json2.encode({
'host': ns.host
'ttl': '${ns.ttl}'
}))!
}
}
value := json.encode({
value := json2.encode({
'ns': ns_records
})
redis.hset(domain, 'subdel', value)!
@@ -162,7 +165,7 @@ pub fn (rs DNSRecordSet) set(domain string) ! {
// Store SOA and root NS records at @
if soa := rs.soa {
mut root_records := map[string]json2.Any{}
root_records['soa'] = json2.Any(json2.map_from({
root_records['soa'] = json2.raw_decode(json2.encode({
'ttl': '${soa.ttl}'
'minttl': '${soa.minttl}'
'mbox': '${soa.mbox}'
@@ -170,20 +173,20 @@ pub fn (rs DNSRecordSet) set(domain string) ! {
'refresh': '${soa.refresh}'
'retry': '${soa.retry}'
'expire': '${soa.expire}'
}))
}))!
if rs.ns.len > 0 {
mut ns_records := []map[string]string{}
mut ns_records := []json2.Any{}
for ns in rs.ns {
ns_records << {
ns_records << json2.raw_decode(json2.encode({
'host': ns.host
'ttl': '${ns.ttl}'
}))!
}
}
root_records['ns'] = json2.Any(json2.map_from(ns_records))
root_records['ns'] = json2.raw_decode(ns_records.str())!
}
redis.hset(domain, '@', json.encode(root_records))!
redis.hset(domain, '@', json2.encode(root_records))!
}
}

View File

@@ -113,7 +113,7 @@ pub fn ipaddr_pub_get() !string {
//also check the address is on local interface
pub fn ipaddr_pub_get_check() !string {
// Check if the public IP matches any local interface
public_ip := ipaddr_pub_get_check()!
public_ip := ipaddr_pub_get()!
if !is_ip_on_local_interface(public_ip)! {
return error('Public IP ${public_ip} is NOT bound to any local interface (possibly behind a NAT firewall).')
}
@@ -123,7 +123,7 @@ pub fn ipaddr_pub_get_check() !string {
// Check if the public IP matches any of the local network interfaces
pub fn is_ip_on_local_interface(public_ip string) !bool {
interfaces := exec(cmd: 'ip addr show', stdout: false) or {
return error('Failed to enumerate network interfaces.')
return error('Failed to enumerate network interfaces: ${err}')
}
lines := interfaces.output.split('\n')