From 37cc1a84f6f7505f62b3f7d4a7e855dc03880a34 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 6 Jan 2024 04:32:54 -0600 Subject: [PATCH] add LinuxStatus() Signed-off-by: Jeff Carr --- fix.go | 44 +++++++++++++++++++ gui.go | 24 ++-------- hostname.go | 11 ----- hostnameStatus.go | 2 +- linuxstatus/args.go | 61 ++++++++++++++++++++++++++ linuxstatus/common.go | 34 +++++++++++++++ linuxstatus/draw.go | 30 +++++++++++++ linuxstatus/hostname.go | 84 +++++++++++++++++++++++++++++++++++ linuxstatus/new.go | 17 ++++++++ linuxstatus/structs.go | 35 +++++++++++++++ linuxstatus/unix.go | 97 +++++++++++++++++++++++++++++++++++++++++ main.go | 4 ++ structs.go | 4 +- 13 files changed, 414 insertions(+), 33 deletions(-) create mode 100644 fix.go create mode 100644 linuxstatus/args.go create mode 100644 linuxstatus/common.go create mode 100644 linuxstatus/draw.go create mode 100644 linuxstatus/hostname.go create mode 100644 linuxstatus/new.go create mode 100644 linuxstatus/structs.go create mode 100644 linuxstatus/unix.go diff --git a/fix.go b/fix.go new file mode 100644 index 0000000..6bc0896 --- /dev/null +++ b/fix.go @@ -0,0 +1,44 @@ +// This creates a simple hello world window +package main + +import ( + "go.wit.com/log" +) + +func fix() bool { + log.Warn("") + if ! me.status.Ready() { + log.Warn("The IPv6 Control Panel is not Ready() yet") + return false + } + if me.status.ValidHostname() { + log.Warn("Your hostname is VALID:", me.status.GetHostname()) + } else { + log.Warn("You must first fix your hostname:", me.status.GetHostname()) + return false + } + if me.digStatus.IPv4() { + log.Warn("IPv4 addresses are resolving") + } else { + log.Warn("You must first figure out why you can't look up IPv4 addresses") + log.Warn("Are you on the internet at all?") + return false + } + if me.digStatus.IPv6() { + log.Warn("IPv6 addresses are resolving") + } else { + log.Warn("You must first figure out why you can't look up IPv6 addresses") + return false + } + if ! me.status.IPv4() { + log.Warn("You do not have real IPv4 addresses. Nothing to fix here") + } + if ! me.status.IPv6() { + log.Warn("IPv6 DNS is broken. Check what is broken here") + log.Warn("What are my IPv6 addresses?") + log.Warn("What are the AAAA resource records in DNS?") + return false + } + log.Warn("YOU SHOULD BE IN IPv6 BLISS") + return true +} diff --git a/gui.go b/gui.go index 40f75b6..1ff4837 100644 --- a/gui.go +++ b/gui.go @@ -41,7 +41,8 @@ func detailsTab(title string) { grid.SetNext(1,1) grid.NewLabel("domainname =") - me.domainname = grid.NewLabel("domainname") + grid.NewLabel("DEPRECATED") +// me.domainname = grid.NewLabel("domainname") grid.NewLabel("hostname -s =") me.hostshort = grid.NewLabel("hostname -s") @@ -209,24 +210,7 @@ func mainWindow(title string) { // This is where you figure out what to do next to fix the problems gr.NewButton("fix", func () { - if ! me.status.Ready() { - log.Warn("The IPv6 Control Panel is not Ready() yet") - return - } - if me.status.ValidHostname() { - log.Warn("Your hostname is VALID:", me.status.GetHostname()) - } else { - log.Warn("You must first fix your hostname:", me.status.GetHostname()) - return - } - if ! me.status.IPv4() { - log.Warn("You do not have real IPv4 addresses. Nothing to fix here") - } - if ! me.status.IPv6() { - log.Warn("IPv6 DNS is broken. Check what is broken here") - return - } - log.Warn("FIGURE OUT WHAT TO DO HERE") + fix() }) grid.Margin() @@ -368,7 +352,7 @@ func updateDNS() { // lookup the NS records for your domain // if your host is test.wit.com, find the NS resource records for wit.com - lookupNS(me.domainname.S) + lookupNS(me.statusOS.GetDomainName()) log.Println("updateDNS() END") } diff --git a/hostname.go b/hostname.go index 062f033..9ca821f 100644 --- a/hostname.go +++ b/hostname.go @@ -25,18 +25,7 @@ func getHostname() { me.status.SetHostname(s) dn := run("domainname") - if (me.domainname.S != dn) { - log.Log(CHANGE, "domainname has changed from", me.domainname.S, "to", dn) - me.domainname.SetText(dn) - me.changed = true - } - hshort := run("hostname -s") - if (me.hostshort.S != hshort) { - log.Log(CHANGE, "hostname -s has changed from", me.hostshort.S, "to", hshort) - me.hostshort.SetText(hshort) - me.changed = true - } var test string test = hshort + "." + dn diff --git a/hostnameStatus.go b/hostnameStatus.go index b58fb04..bc13f6a 100644 --- a/hostnameStatus.go +++ b/hostnameStatus.go @@ -297,7 +297,7 @@ func (hs *hostnameStatus) updateStatus() { log.Log(STATUS, "updateStatus() START") hs.hostShort.Set(me.hostshort.S) - hs.domainname.Set(me.domainname.S) + hs.domainname.Set(me.statusOS.GetDomainName()) if hs.ValidHostname() { vals = lookupDoH(hs.GetHostname(), "AAAA") diff --git a/linuxstatus/args.go b/linuxstatus/args.go new file mode 100644 index 0000000..9457410 --- /dev/null +++ b/linuxstatus/args.go @@ -0,0 +1,61 @@ +package linuxstatus + +/* + this enables command line options from other packages like 'gui' and 'log' +*/ + +import ( + "go.wit.com/log" +) + +var NOW log.LogFlag +var NET log.LogFlag +var DNS log.LogFlag +var PROC log.LogFlag +var SPEW log.LogFlag +var CHANGE log.LogFlag +var STATUS log.LogFlag + +func init() { + NOW.B = false + NOW.Name = "NOW" + NOW.Subsystem = "cpdns" + NOW.Desc = "temp debugging stuff" + NOW.Register() + + NET.B = false + NET.Name = "NET" + NET.Subsystem = "cpdns" + NET.Desc = "Network logging" + NET.Register() + + DNS.B = false + DNS.Name = "DNS" + DNS.Subsystem = "cpdns" + DNS.Desc = "dnsStatus.update()" + DNS.Register() + + PROC.B = false + PROC.Name = "PROC" + PROC.Subsystem = "cpdns" + PROC.Desc = "/proc logging" + PROC.Register() + + SPEW.B = false + SPEW.Name = "SPEW" + SPEW.Subsystem = "cpdns" + SPEW.Desc = "spew logging" + SPEW.Register() + + CHANGE.B = false + CHANGE.Name = "CHANGE" + CHANGE.Subsystem = "cpdns" + CHANGE.Desc = "show droplet state changes" + CHANGE.Register() + + STATUS.B = false + STATUS.Name = "STATUS" + STATUS.Subsystem = "cpdns" + STATUS.Desc = "updateStatus()" + STATUS.Register() +} diff --git a/linuxstatus/common.go b/linuxstatus/common.go new file mode 100644 index 0000000..c4aea10 --- /dev/null +++ b/linuxstatus/common.go @@ -0,0 +1,34 @@ +// This creates a simple hello world window +package linuxstatus + +import ( + "go.wit.com/log" +) + +func (hs *LinuxStatus) Show() { + log.Log(CHANGE, "linuxStatus.Show() window") + hs.window.Show() + hs.hidden = false +} + +func (hs *LinuxStatus) Hide() { + log.Log(CHANGE, "linuxStatus.Hide() window") + hs.window.Hide() + hs.hidden = true +} + +func (hs *LinuxStatus) Toggle() { + log.Log(CHANGE, "linuxStatus.Toggle() window") + if hs.hidden { + hs.window.Show() + } else { + hs.window.Hide() + } +} + +func (hs *LinuxStatus) Ready() bool { + if me == nil {return false} + if hs == nil {return false} + if hs.window == nil {return false} + return me.ready +} diff --git a/linuxstatus/draw.go b/linuxstatus/draw.go new file mode 100644 index 0000000..191c326 --- /dev/null +++ b/linuxstatus/draw.go @@ -0,0 +1,30 @@ +// This creates a simple hello world window +package linuxstatus + +import ( + "go.wit.com/gui/gadgets" +) + +// creates the actual widgets. +// it's assumed you are always passing in a box +func draw(ls *LinuxStatus) { + if ! ls.Ready() {return} + ls.group = ls.window.Box().NewGroup("Real Stuff") + + ls.grid = ls.group.NewGrid("gridnuts", 2, 2) + + ls.grid.SetNext(1,1) + + ls.hostshort = gadgets.NewOneLiner(ls.grid, "hostname -s") + ls.domainname = gadgets.NewOneLiner(ls.grid, "domain name") + ls.NSrr = gadgets.NewOneLiner(ls.grid, "NS records =") + ls.uid = gadgets.NewOneLiner(ls.grid, "UID =") + ls.IPv4 = gadgets.NewOneLiner(ls.grid, "Current IPv4 =") + ls.IPv6 = gadgets.NewOneLiner(ls.grid, "Current IPv6 =") + ls.workingIPv6 = gadgets.NewOneLiner(ls.grid, "Real IPv6 =") + ls.nics = gadgets.NewOneLiner(ls.grid, "network intefaces =") + ls.speedActual = gadgets.NewOneLiner(ls.grid, "refresh speed =") + + ls.grid.Margin() + ls.grid.Pad() +} diff --git a/linuxstatus/hostname.go b/linuxstatus/hostname.go new file mode 100644 index 0000000..b8d60ef --- /dev/null +++ b/linuxstatus/hostname.go @@ -0,0 +1,84 @@ +// figures out if your hostname is valid +// then checks if your DNS is setup correctly +package linuxstatus + +import ( + "go.wit.com/log" + "go.wit.com/shell" + + // will try to get this hosts FQDN + "github.com/Showmax/go-fqdn" +) + +func (ls *LinuxStatus) GetDomainName() string { + return me.domainname.Get() +} + +func (ls *LinuxStatus) setDomainName(dn string) { + me.domainname.Set(dn) +} + +func getHostname() { + var err error + var s string = "gui.Label == nil" + s, err = fqdn.FqdnHostname() + if (err != nil) { + log.Error(err, "FQDN hostname error") + return + } + log.Warn("full hostname should be:", s) + + dn := run("domainname") + if (me.domainname.Get() != dn) { + log.Log(CHANGE, "domainname has changed from", me.GetDomainName(), "to", dn) + me.setDomainName(dn) + me.changed = true + } + + hshort := run("hostname -s") + if (me.hostshort.Get() != hshort) { + log.Log(CHANGE, "hostname -s has changed from", me.hostshort.Get(), "to", hshort) + me.hostshort.Set(hshort) + me.changed = true + } + + /* + var test string + test = hshort + "." + dn + if (me.status.GetHostname() != test) { + log.Log(CHANGE, "me.hostname", me.status.GetHostname(), "does not equal", test) + if (me.hostnameStatus.S != "BROKEN") { + log.Log(CHANGE, "me.hostname", me.status.GetHostname(), "does not equal", test) + me.changed = true + me.hostnameStatus.SetText("BROKEN") + } + } else { + if (me.hostnameStatus.S != "VALID") { + log.Log(CHANGE, "me.hostname", me.status.GetHostname(), "is valid") + me.hostnameStatus.SetText("VALID") + me.changed = true + } + } + */ +} + +// returns true if the hostname is good +// check that all the OS settings are correct here +// On Linux, /etc/hosts, /etc/hostname +// and domainname and hostname +func goodHostname() bool { + hostname := shell.Chomp(shell.Cat("/etc/hostname")) + log.Log(NOW, "hostname =", hostname) + + hs := run("hostname -s") + dn := run("domainname") + log.Log(NOW, "hostname short =", hs, "domainname =", dn) + + tmp := hs + "." + dn + if (hostname == tmp) { + log.Log(NOW, "hostname seems to be good", hostname) + return true + } + + return false +} diff --git a/linuxstatus/new.go b/linuxstatus/new.go new file mode 100644 index 0000000..0ce504c --- /dev/null +++ b/linuxstatus/new.go @@ -0,0 +1,17 @@ +// This creates a simple hello world window +package linuxstatus + +import ( +) + +func New() *LinuxStatus { + me = &LinuxStatus { + hidden: true, + ready: false, + } + + me.init = true + return me + + // me.window = gadgets.NewBasicWindow(me.myGui, "Linux OS Details") +} diff --git a/linuxstatus/structs.go b/linuxstatus/structs.go new file mode 100644 index 0000000..be7f8f4 --- /dev/null +++ b/linuxstatus/structs.go @@ -0,0 +1,35 @@ +/* + figures out if your hostname is valid + then checks if your DNS is setup correctly +*/ + +package linuxstatus + +import ( + "go.wit.com/gui/gui" + "go.wit.com/gui/gadgets" +) + +var me *LinuxStatus + +type LinuxStatus struct { + init bool + ready bool + hidden bool + changed bool + + window *gadgets.BasicWindow + group *gui.Node + grid *gui.Node + + hostshort *gadgets.OneLiner + domainname *gadgets.OneLiner + NSrr *gadgets.OneLiner + uid *gadgets.OneLiner + IPv4 *gadgets.OneLiner + IPv6 *gadgets.OneLiner + workingIPv6 *gadgets.OneLiner + nics *gadgets.OneLiner + speedActual *gadgets.OneLiner + +} diff --git a/linuxstatus/unix.go b/linuxstatus/unix.go new file mode 100644 index 0000000..99509c0 --- /dev/null +++ b/linuxstatus/unix.go @@ -0,0 +1,97 @@ +// Various Linux/Unix'y things + +// https://wiki.archlinux.org/title/Dynamic_DNS + +package linuxstatus + +import ( + "os" + "os/exec" + "net" + "bytes" + "fmt" + "strings" + + "go.wit.com/log" + "go.wit.com/shell" +) + +func CheckSuperuser() bool { + return os.Getuid() == 0 +} + +func Escalate() { + if os.Getuid() != 0 { + cmd := exec.Command("sudo", "./control-panel-dns") // TODO: get the actual path + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + log.Error(err, "exit in Escalate()") + log.Exit(err) + } + } +} + +// You need permission to do a zone transfer. Otherwise: +// dig +noall +answer +multiline lab.wit.com any +// dig +all +multiline fire.lab.wit.com # gives the zonefile header (ttl vals) +func DumpPublicDNSZone(zone string) { + entries, err := net.LookupHost(zone) + if err != nil { + panic(err) + } + for _, entry := range entries { + log.Println(entry) + } +} + +func dumpIPs(host string) { + ips, err := net.LookupIP(host) + if err != nil { + log.Error(err, "dumpIPs() failed") + } + for _, ip := range ips { + log.Println(host, ip) + } +} + +/* + check if ddclient is installed, working, and/or configured + https://github.com/ddclient/ddclient +*/ +func ddclient() { +} + +/* + check if ddupdate is installed, working, and/or configured +*/ +func ddupdate() { +} + +func run(s string) string { + cmdArgs := strings.Fields(s) + // Define the command you want to run + // cmd := exec.Command(cmdArgs) + cmd := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...) + + // Create a buffer to capture the output + var out bytes.Buffer + + // Set the output of the command to the buffer + cmd.Stdout = &out + + // Run the command + err := cmd.Run() + if err != nil { + fmt.Println("Error running command:", err) + return "" + } + + tmp := shell.Chomp(out.String()) + // Output the results + log.Info("Command Output:", tmp) + + return tmp +} diff --git a/main.go b/main.go index f417b86..5eb83f6 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,8 @@ import ( "go.wit.com/gui/gui" "go.wit.com/gui/debugger" + "go.wit.com/control-panels/dns/linuxstatus" + "github.com/miekg/dns" ) @@ -47,6 +49,8 @@ func main() { me.digStatus = NewDigStatusWindow(me.myGui) me.status = NewHostnameStatusWindow(me.myGui) + linuxstatus.New() + if debugger.ArgDebug() { log.Sleep(2) debugger.DebugWindow(me.myGui) diff --git a/structs.go b/structs.go index c3f6622..e8db7ee 100644 --- a/structs.go +++ b/structs.go @@ -6,6 +6,7 @@ import ( "time" "go.wit.com/gui/gui" "go.wit.com/gui/gadgets" + "go.wit.com/control-panels/dns/linuxstatus" "github.com/miekg/dns" ) @@ -15,10 +16,11 @@ var me Host type Host struct { status *hostnameStatus // keeps track of the hostname and it's status + statusOS *linuxstatus.LinuxStatus // what the Linux OS sees hostnameStatus *gui.Node // a summary for the user of where things are - domainname *gui.Node // kernel.org + // domainname *gui.Node // kernel.org hostshort *gui.Node // hostname -s artificialSleep float64 `default:"0.7"` // artificial sleep on startup