Skip to content

Commit

Permalink
WIP(osal.coredns): add example for coredns usage
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
mariobassem committed Feb 10, 2025
1 parent 86e3fdb commit 3117d28
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 31 deletions.
38 changes: 32 additions & 6 deletions examples/osal/coredns/example.vsh
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -11,10 +11,36 @@ installer.start()!

// TODO: create heroscript and run it to add dns records
mut script := '
dns.a_record
name: "a_rec1"
ip: "1.1.1.1"
'
!!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')!
2 changes: 1 addition & 1 deletion install_v.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions lib/installers/infra/coredns/coredns_actions.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 21 additions & 18 deletions lib/osal/coredns/populator.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module coredns

import json
import freeflowuniverse.herolib.core.redisclient
import x.json2

Expand Down Expand Up @@ -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}'
Expand Down Expand Up @@ -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}'
Expand All @@ -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)!
Expand All @@ -162,28 +165,28 @@ 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}'
'ns': '${soa.ns}'
'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))!
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/osal/net.v
Original file line number Diff line number Diff line change
Expand Up @@ -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).')
}
Expand All @@ -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')

Expand Down

0 comments on commit 3117d28

Please sign in to comment.