2019-02-01 07:28:17 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import "log"
|
2019-05-06 20:57:59 -05:00
|
|
|
import "os"
|
2019-05-06 19:42:59 -05:00
|
|
|
import "time"
|
2019-06-06 11:35:17 -05:00
|
|
|
import "reflect"
|
2019-06-06 12:53:00 -05:00
|
|
|
// import "os/signal"
|
|
|
|
// import "syscall"
|
|
|
|
// import "runtime"
|
2019-05-24 20:41:31 -05:00
|
|
|
|
2019-05-24 22:53:44 -05:00
|
|
|
// this is the king of dns libraries
|
|
|
|
import "github.com/miekg/dns"
|
|
|
|
|
2019-05-24 20:41:31 -05:00
|
|
|
import "git.wit.com/wit/gui"
|
2019-06-02 21:56:14 -05:00
|
|
|
import pb "git.wit.com/wit/witProtobuf"
|
2019-05-24 22:53:44 -05:00
|
|
|
import "git.wit.com/jcarr/dnssecsocket"
|
2019-06-06 11:35:17 -05:00
|
|
|
import "git.wit.com/wit/shell"
|
2019-02-01 07:28:17 -06:00
|
|
|
|
2019-05-23 11:47:48 -05:00
|
|
|
import "github.com/gobuffalo/packr"
|
2019-05-24 17:35:57 -05:00
|
|
|
import "github.com/davecgh/go-spew/spew"
|
2019-02-01 07:28:17 -06:00
|
|
|
|
2019-05-23 02:11:49 -05:00
|
|
|
var GITCOMMIT string // this is passed in as an ldflag
|
|
|
|
var GOVERSION string // this is passed in as an ldflag
|
2019-05-24 02:21:15 -05:00
|
|
|
var BUILDTIME string // this is passed in as an ldflag
|
2019-06-02 00:24:26 -05:00
|
|
|
var VERSION string // this is passed in as an ldflag
|
2019-05-23 02:11:49 -05:00
|
|
|
|
2019-06-03 00:22:23 -05:00
|
|
|
var State string // used as a State machine
|
2019-06-06 11:35:17 -05:00
|
|
|
var sigChan chan os.Signal
|
|
|
|
var errChan chan interface{}
|
2019-06-03 00:22:23 -05:00
|
|
|
|
2019-06-02 21:56:14 -05:00
|
|
|
type myButtonInfo struct {
|
|
|
|
Account *pb.Account // associated with what account?
|
|
|
|
Accounts []*pb.Account // associated with what account?
|
|
|
|
VM *pb.Event_VM // associated with which VM?
|
|
|
|
Custom func (*gui.GuiButton)
|
|
|
|
ADD func (*gui.GuiButton)
|
|
|
|
Name string
|
2019-06-02 22:50:16 -05:00
|
|
|
Action string
|
2019-06-02 21:56:14 -05:00
|
|
|
}
|
|
|
|
|
2019-02-01 07:28:17 -06:00
|
|
|
// use mergo to merge structs
|
|
|
|
// import "github.com/imdario/mergo"
|
|
|
|
// mergo.Merge(&dest, src)
|
|
|
|
|
|
|
|
// always sorted slice (new project)
|
|
|
|
// https://github.com/yaa110/sslice
|
|
|
|
|
2019-05-12 08:18:06 -05:00
|
|
|
// several smart slice functions (new project. April 2019)
|
|
|
|
// https://github.com/elliotchance/pie
|
|
|
|
|
2019-05-25 23:28:21 -05:00
|
|
|
// look into this for dns if possible
|
|
|
|
// https://en.wikipedia.org/wiki/DNSCrypt
|
|
|
|
// https://en.wikipedia.org/wiki/DNS_over_HTTPS
|
|
|
|
|
|
|
|
// DNS over TLS plugin for coredns
|
|
|
|
// uses protobuf's and gRPC in pb/dns.proto
|
|
|
|
// https://github.com/coredns/coredns/tree/master/plugin/tls
|
2019-05-26 02:27:15 -05:00
|
|
|
// https://github.com/coredns/coredns/blob/master/pb/dns.proto
|
2019-05-25 23:28:21 -05:00
|
|
|
|
2019-05-26 03:05:28 -05:00
|
|
|
// cross platform openvpn that may work for IPv6
|
|
|
|
// https://github.com/mysteriumnetwork/go-openvpnwe
|
|
|
|
|
2019-06-03 17:45:25 -05:00
|
|
|
// i18n with 'po' file support
|
|
|
|
// https://github.com/leonelquinteros/gotext
|
|
|
|
|
2019-06-06 11:35:17 -05:00
|
|
|
// a good example of using interface{}
|
|
|
|
// https://github.com/Jeffail/tunny
|
|
|
|
|
2019-05-23 13:33:30 -05:00
|
|
|
func onExit(err error) {
|
2019-05-12 01:21:57 -05:00
|
|
|
log.Println("Sleep for 1 second")
|
|
|
|
time.Sleep(1 * 1000 * 1000 * 1000)
|
|
|
|
|
2019-05-25 01:53:52 -05:00
|
|
|
// save the protobuf.Config as a JSON config file
|
|
|
|
saveConfig()
|
2019-05-12 01:21:57 -05:00
|
|
|
|
2019-05-23 13:33:30 -05:00
|
|
|
if (err != nil) {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2019-05-12 01:21:57 -05:00
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
|
2019-05-24 13:32:26 -05:00
|
|
|
var packrBox packr.Box
|
|
|
|
|
2019-05-24 22:53:44 -05:00
|
|
|
func lookupAAAA(hostname string) string {
|
|
|
|
// lookup the IP address from DNS
|
|
|
|
dnsRR := dnssecsocket.Dnstrace(hostname, "AAAA")
|
|
|
|
spew.Dump(dnsRR)
|
2019-05-24 23:50:23 -05:00
|
|
|
if (dnsRR == nil) {
|
|
|
|
return "BROKEN"
|
|
|
|
}
|
2019-05-24 22:53:44 -05:00
|
|
|
ipaddr := dns.Field(dnsRR, 1)
|
|
|
|
log.Println("ipaddr", ipaddr)
|
|
|
|
return ipaddr
|
|
|
|
}
|
|
|
|
|
2019-05-10 03:21:32 -05:00
|
|
|
func main() {
|
2019-06-06 11:35:17 -05:00
|
|
|
go handleErrors()
|
|
|
|
|
2019-05-23 11:47:48 -05:00
|
|
|
// This puts all the files in that directory in the binary
|
|
|
|
// This directory includes the default config file if there is not already one
|
2019-05-24 13:32:26 -05:00
|
|
|
packrBox = packr.NewBox("./resources")
|
2019-05-24 19:39:05 -05:00
|
|
|
|
2019-05-24 20:41:31 -05:00
|
|
|
// This will parse the command line and config file
|
2019-05-25 01:53:52 -05:00
|
|
|
// This uses a protobuf definition and then Marshal's
|
|
|
|
// and unmarshal's that into a JSON config file
|
|
|
|
// that is human readable and editable. This is the easy way
|
|
|
|
// to pass around a configuration structure throughout a
|
|
|
|
// golang application IMHO
|
|
|
|
parseConfig()
|
|
|
|
|
2019-06-05 04:52:35 -05:00
|
|
|
if (config.Dirty) {
|
|
|
|
config.Version = VERSION + " (dirty)"
|
|
|
|
} else {
|
|
|
|
config.Version = VERSION
|
|
|
|
}
|
|
|
|
|
2019-05-25 01:53:52 -05:00
|
|
|
for key, foo := range config.Accounts {
|
|
|
|
log.Println("FOUND ACCOUNT = ", key, foo)
|
2019-05-24 20:17:53 -05:00
|
|
|
}
|
|
|
|
|
2019-05-11 09:53:32 -05:00
|
|
|
initChannel()
|
|
|
|
go processEvents()
|
|
|
|
|
2019-06-03 19:05:36 -05:00
|
|
|
v185AAAA := lookupAAAA("v000185.testing.com.customers.wprod.wit.com")
|
|
|
|
log.Println("v185AAA = ", v185AAAA)
|
2019-06-05 04:52:35 -05:00
|
|
|
// go gorillaDial("ccp.wit.com:9000")
|
|
|
|
go gorillaDial("stackapi-ccp.stackapi.customers.wit.com:9000")
|
2019-06-01 23:15:36 -05:00
|
|
|
go gui.WatchGUI()
|
2019-05-07 16:54:08 -05:00
|
|
|
|
2019-05-24 23:50:23 -05:00
|
|
|
// use this to discover what the OS thinks it's hostname is
|
|
|
|
// seems to be cross platform (?)
|
2019-05-29 04:28:19 -05:00
|
|
|
// Windows: WMIC computersystem where caption='current_pc_name' rename new_pc_name
|
2019-06-02 22:07:13 -05:00
|
|
|
hostname := fqdnGet()
|
|
|
|
log.Println("fqdnGet() = ", hostname)
|
2019-06-02 17:50:11 -05:00
|
|
|
config.Hostname = hostname
|
2019-05-24 23:50:23 -05:00
|
|
|
|
|
|
|
// this is a recursive dig for the AAAA record
|
|
|
|
// TODO: check for dns hijacking
|
2019-05-24 22:53:44 -05:00
|
|
|
ipAAAA := lookupAAAA(hostname)
|
2019-06-02 17:50:11 -05:00
|
|
|
config.IPv6 = ipAAAA
|
2019-05-24 00:47:26 -05:00
|
|
|
|
2019-05-24 22:53:44 -05:00
|
|
|
gui.Data.MouseClick = mainMouseClick
|
2019-05-24 11:04:36 -05:00
|
|
|
|
2019-06-02 17:50:11 -05:00
|
|
|
gui.Config.Width = int(config.Width)
|
|
|
|
gui.Config.Height = int(config.Height)
|
2019-05-23 13:33:30 -05:00
|
|
|
|
2019-06-02 17:50:11 -05:00
|
|
|
// Set output debugging level
|
|
|
|
gui.Config.Debug = config.Debug
|
|
|
|
gui.Config.DebugTable = config.Debugtable
|
|
|
|
log.Println("gui.Config.Debug = ", gui.Config.Debug)
|
|
|
|
log.Println("gui.Config.DebugTable = ", gui.Config.DebugTable)
|
2019-05-23 13:33:30 -05:00
|
|
|
|
|
|
|
// Get "Real" User under sudo.
|
|
|
|
// More Info: https://stackoverflow.com/q/29733575/402585
|
|
|
|
log.Println("Real User: " + os.Getenv("SUDO_USER"))
|
2019-05-23 00:33:16 -05:00
|
|
|
|
2019-05-10 03:21:32 -05:00
|
|
|
// make this the main loop in an attempt to figure out the crashes
|
|
|
|
// do not change this until the GUI is stable
|
2019-06-04 02:56:36 -05:00
|
|
|
gui.StartNewWindow(false, "Cloud Control Panel", gui.Yaxis, showSplashBox)
|
2019-06-06 12:44:10 -05:00
|
|
|
if (os.Getenv("DISPLAY") == "") {
|
|
|
|
log.Println("gui.StartNewWindow() END DISPLAY =", os.Getenv("DISPLAY"))
|
|
|
|
log.Println("gui.StartNewWindow() Probably this died because your DISPLAY is not set")
|
|
|
|
}
|
|
|
|
log.Println("gui.StartNewWindow() END")
|
2019-05-23 00:33:16 -05:00
|
|
|
}
|
2019-05-10 03:21:32 -05:00
|
|
|
|
2019-05-28 18:47:16 -05:00
|
|
|
//
|
|
|
|
// This is GO language concept for 'recover' to keep an app from completely crashing
|
2019-05-26 05:13:09 -05:00
|
|
|
//
|
2019-05-26 04:58:29 -05:00
|
|
|
// Doing this can sometimes avoid a panic() on things like:
|
|
|
|
// panic: runtime error: slice bounds out of range
|
2019-05-26 05:13:09 -05:00
|
|
|
//
|
|
|
|
// In debugging mode, always panic() and never try to recover()
|
|
|
|
//
|
2019-05-26 04:58:29 -05:00
|
|
|
func r() {
|
2019-06-02 17:50:11 -05:00
|
|
|
if (gui.Config.Debug == false) {
|
2019-05-26 05:13:09 -05:00
|
|
|
if r := recover(); r != nil {
|
|
|
|
log.Println("recover() SOMETHING IS REALLY BROKEN r =", r)
|
|
|
|
log.Println("recover() SOMETHING IS REALLY BROKEN r =", r)
|
|
|
|
log.Println("recover() SOMETHING IS REALLY BROKEN r =", r)
|
2019-05-31 22:14:33 -05:00
|
|
|
panic("something")
|
2019-05-26 05:13:09 -05:00
|
|
|
}
|
2019-05-26 04:58:29 -05:00
|
|
|
}
|
|
|
|
}
|
2019-06-06 11:35:17 -05:00
|
|
|
|
|
|
|
func init() {
|
|
|
|
log.Println("init() WAS HERE")
|
|
|
|
log.Println("init() WAS HERE")
|
|
|
|
log.Println("init() WAS HERE")
|
|
|
|
|
|
|
|
errChan = make(chan interface{}, 3)
|
|
|
|
shell.InitCallback(handleShell) // asks for all the shell errors to be sent here
|
|
|
|
|
2019-06-06 12:53:00 -05:00
|
|
|
/*
|
2019-06-06 11:35:17 -05:00
|
|
|
sigChan = make(chan os.Signal, 3)
|
2019-06-06 12:37:36 -05:00
|
|
|
if runtime.GOOS != "windows" {
|
|
|
|
log.Println("loadConfigFile() OS: Windows")
|
2019-06-06 12:44:10 -05:00
|
|
|
signal.Notify(sigChan, syscall.SIGUSR1)
|
2019-06-06 12:37:36 -05:00
|
|
|
}
|
2019-06-06 12:53:00 -05:00
|
|
|
*/
|
2019-06-06 11:35:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// get's sent the return values and errors from git.wit.com/wit/shell/
|
|
|
|
func handleShell(err interface{}, ret int) {
|
|
|
|
log.Println("shell.Run() END Returned ", ret)
|
|
|
|
errChan <- err
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleErrors() {
|
|
|
|
for val := range errChan {
|
|
|
|
log.Println("handleErrors() val =", val)
|
|
|
|
log.Println("handleErrors() reflect.TypeOf(val) =", reflect.TypeOf(val))
|
|
|
|
log.Printf("handleErrors() val type T = %T\n", val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// trap signals
|
|
|
|
/*
|
|
|
|
go func() {
|
|
|
|
s := make(chan os.Signal, 1)
|
|
|
|
signal.Notify(s, syscall.SIGQUIT)
|
|
|
|
<-s
|
|
|
|
panic("give me the stack")
|
|
|
|
}()
|
|
|
|
*/
|