|
|
|
@ -2,6 +2,7 @@ package main
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"context" |
|
|
|
|
"crypto/rand" |
|
|
|
|
"crypto/sha256" |
|
|
|
|
"crypto/tls" |
|
|
|
|
"crypto/x509" |
|
|
|
@ -55,6 +56,8 @@ type DaemonAPI struct {
|
|
|
|
|
ApplyConfigStatuses []string |
|
|
|
|
ApplyConfigStatusIndex int |
|
|
|
|
ApplyConfigStatusError string |
|
|
|
|
|
|
|
|
|
TelemetryID string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type ThresholdConfig struct { |
|
|
|
@ -87,6 +90,7 @@ type Status struct {
|
|
|
|
|
ServerName string `json:"server_name"` |
|
|
|
|
GUITunnels []GUITunnel `json:"tunnels"` |
|
|
|
|
UpdateTenantInfoMessage string `json:"update_tenant_info_message"` |
|
|
|
|
DaemonTelemetryID string `json:"daemon_telemetry_id"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type TenantInfo struct { |
|
|
|
@ -195,6 +199,8 @@ const caddyAdminSocketFile = "/var/run/greenhouse-daemon-caddy-admin.sock"
|
|
|
|
|
const mainCAName = "greenhouse_daemon_localhost_ca" |
|
|
|
|
|
|
|
|
|
var log child.LogManager |
|
|
|
|
var daemonTelemetryId string |
|
|
|
|
var daemonTelemetryAccount string |
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
|
|
|
|
|
@ -214,7 +220,7 @@ func main() {
|
|
|
|
|
daemonExecutablePath = filepath.Dir(executableLocation) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon because operating system '%s' is not supported yet\n\n", runtime.GOOS) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because operating system '%s' is not supported yet\n\n", runtime.GOOS) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -246,7 +252,7 @@ func main() {
|
|
|
|
|
caddyExecutable = filepath.Join(daemonExecutablePath, caddyExecutable) |
|
|
|
|
caddyConfigAbsPath, err := filepath.Abs("caddy-config.json") |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon because can't resolve absolute path of \"caddy-config.json\": %+v\n\n", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because can't resolve absolute path of \"caddy-config.json\": %+v\n\n", err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
caddyArguments := []string{"run", "-config", caddyConfigAbsPath} |
|
|
|
@ -258,14 +264,26 @@ func main() {
|
|
|
|
|
fmt.Sprintf("XDG_CONFIG_HOME=%s", filepath.Join(daemonPath, "caddyConfig")), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
daemonTelemetryIdBytes, err := ioutil.ReadFile(filepath.Join(daemonPath, "daemon-telemetry-id.txt")) |
|
|
|
|
if err == nil { |
|
|
|
|
daemonTelemetryId = string(daemonTelemetryIdBytes) |
|
|
|
|
} else { |
|
|
|
|
buffer := make([]byte, 4) |
|
|
|
|
n, err := rand.Read(buffer) |
|
|
|
|
if n != 4 || err != nil { |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon, can't read 4 random bytes: read: %d err: %+v", n, err) |
|
|
|
|
} |
|
|
|
|
daemonTelemetryId = fmt.Sprintf("%x", buffer) |
|
|
|
|
ioutil.WriteFile(filepath.Join(daemonPath, "daemon-telemetry-id.txt"), []byte(daemonTelemetryId), 0755) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var daemonConfig DaemonConfig |
|
|
|
|
daemonConfigBytes, err := ioutil.ReadFile(filepath.Join(daemonPath, "daemon-config.json")) |
|
|
|
|
// if the file doesn't exist, just skip it.
|
|
|
|
|
if err == nil { |
|
|
|
|
err = json.Unmarshal(daemonConfigBytes, &daemonConfig) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon, can't parse daemon-config.json %+v", err) |
|
|
|
|
os.Exit(1) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon, can't parse daemon-config.json %+v", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -275,9 +293,10 @@ func main() {
|
|
|
|
|
if err == nil { |
|
|
|
|
err = json.Unmarshal(tenantInfoBytes, &tenantInfo) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon, can't parse daemon-tenant-info.json %+v", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon, can't parse daemon-tenant-info.json %+v", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
daemonTelemetryAccount = tenantInfo.EmailAddress |
|
|
|
|
|
|
|
|
|
var thresholdConfig ThresholdConfig |
|
|
|
|
thresholdConfigBytes, err := ioutil.ReadFile(filepath.Join(daemonPath, "threshold-config.json")) |
|
|
|
@ -285,7 +304,7 @@ func main() {
|
|
|
|
|
if err == nil { |
|
|
|
|
err = json.Unmarshal(thresholdConfigBytes, &thresholdConfig) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon, can't parse threshold-config.json %+v", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon, can't parse threshold-config.json %+v", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -332,7 +351,8 @@ func main() {
|
|
|
|
|
daemonConfig.TunnelsEnabled, |
|
|
|
|
child.NewDaemonLogManager(daemonPath, thresholdExecutable), |
|
|
|
|
), |
|
|
|
|
LogManager: log, |
|
|
|
|
LogManager: log, |
|
|
|
|
TelemetryID: daemonTelemetryId, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
go daemonAPIInstance.ThresholdService.MainLoop() |
|
|
|
@ -355,7 +375,7 @@ func main() {
|
|
|
|
|
if missingAnyCertsOrKeys && !useUnixSockets { |
|
|
|
|
err = GenerateTLSCertificatesAndKeys(daemonPath) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon because GenerateTLSCertificatesAndKeys returned %+v", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because GenerateTLSCertificatesAndKeys returned %+v", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -368,11 +388,11 @@ func main() {
|
|
|
|
|
// the unix socket will only be used if useUnixSockets == true
|
|
|
|
|
thresholdClient, err := daemonAPIInstance.MakeServiceClient(thresholdAdminSocketFile) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon because can't make threshold client: %+v", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because can't make threshold client: %+v", err) |
|
|
|
|
} |
|
|
|
|
caddyAdminClient, err := daemonAPIInstance.MakeServiceClient(caddyAdminSocketFile) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon because can't make caddy admin client: %+v", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because can't make caddy admin client: %+v", err) |
|
|
|
|
} |
|
|
|
|
thresholdAdminURL := fmt.Sprintf("https://127.0.0.1:%d", thresholdAdminPort) |
|
|
|
|
caddyAdminURL := fmt.Sprintf("https://127.0.0.1:%d", caddyAdminPort) |
|
|
|
@ -389,6 +409,7 @@ func main() {
|
|
|
|
|
CaddyAdminBaseURL: caddyAdminURL, |
|
|
|
|
ThresholdClient: thresholdClient, |
|
|
|
|
CaddyAdminClient: caddyAdminClient, |
|
|
|
|
TelemetryID: daemonTelemetryId, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if daemonAPIInstance.Config.TunnelsEnabled && len(daemonAPIInstance.Config.GUITunnels) > 0 { |
|
|
|
@ -402,7 +423,7 @@ func main() {
|
|
|
|
|
|
|
|
|
|
thresholdConfig, caddyConfig, err := daemonAPIInstance.ConfigService.PrepareConfigs(daemonAPIInstance.Config.GUITunnels) |
|
|
|
|
if err != nil { |
|
|
|
|
log.Fatalf("can't start the greenhouse-daemon because daemon-config.json is invalid: %+v", err) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because daemon-config.json is invalid: %+v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
completionChannel := make(chan bool) |
|
|
|
@ -421,12 +442,12 @@ func main() {
|
|
|
|
|
|
|
|
|
|
listenAddress, err := net.ResolveUnixAddr("unix", daemonSocketFile) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(fmt.Sprintf("can't start the greenhouse-daemon because net.ResolveUnixAddr() returned %+v", err)) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because net.ResolveUnixAddr() returned %+v", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
listener, err = net.ListenUnix("unix", listenAddress) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(fmt.Sprintf("can't start the greenhouse-daemon because net.ListenUnix(\"unix\", \"%s\") returned %+v", listenAddress, err)) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because net.ListenUnix(\"unix\", \"%s\") returned %+v", listenAddress, err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
log.Printf("greenhouse-daemon about to start listening at http://%s 😈\n", daemonSocketFile) |
|
|
|
@ -435,18 +456,18 @@ func main() {
|
|
|
|
|
addrString := fmt.Sprintf("127.0.0.1:%d", daemonAdminPort) |
|
|
|
|
addr, err := net.ResolveTCPAddr("tcp", addrString) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(fmt.Sprintf("can't start the greenhouse-daemon because net.ResolveTCPAddr(%s) returned %+v", addrString, err)) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because net.ResolveTCPAddr(%s) returned %+v", addrString, err) |
|
|
|
|
} |
|
|
|
|
tcpListener, err := net.ListenTCP("tcp", addr) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(fmt.Sprintf("can't start the greenhouse-daemon because net.ListenTCP(%s) returned %+v", addrString, err)) |
|
|
|
|
fatalfWithTelemetry("can't start the greenhouse-daemon because net.ListenTCP(%s) returned %+v", addrString, err) |
|
|
|
|
} |
|
|
|
|
tlsCert, err := tls.LoadX509KeyPair(daemonAPIInstance.TLSCertFile, daemonAPIInstance.TLSKeyFile) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(fmt.Sprintf( |
|
|
|
|
fatalfWithTelemetry( |
|
|
|
|
"can't start the greenhouse-daemon because tls.LoadX509KeyPair(%s,%s) returned %+v", |
|
|
|
|
daemonAPIInstance.TLSCertFile, daemonAPIInstance.TLSKeyFile, err, |
|
|
|
|
)) |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tlsConfig := &tls.Config{ |
|
|
|
@ -456,6 +477,7 @@ func main() {
|
|
|
|
|
|
|
|
|
|
listener = tls.NewListener(tcpListener, tlsConfig) |
|
|
|
|
|
|
|
|
|
go postTelemetry("daemon-started", daemonTelemetryAccount, daemonTelemetryId, "success!!") |
|
|
|
|
log.Printf("greenhouse-daemon about to start listening at https://%s 😈\n", addrString) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -467,7 +489,7 @@ func main() {
|
|
|
|
|
|
|
|
|
|
go (func() { |
|
|
|
|
err = server.Serve(listener) |
|
|
|
|
log.Fatalf("server.Serve returned %+v", err) |
|
|
|
|
fatalfWithTelemetry("server.Serve returned %+v", err) |
|
|
|
|
})() |
|
|
|
|
|
|
|
|
|
sigs := child.GetSignalChannelOSIndependent() |
|
|
|
@ -475,6 +497,7 @@ func main() {
|
|
|
|
|
go func() { |
|
|
|
|
sig := <-sigs |
|
|
|
|
log.Printf("Greenhouse daemon recieved signal: %s\n", sig) |
|
|
|
|
go postTelemetry("daemon-signal", daemonTelemetryAccount, daemonTelemetryId, sig.String()) |
|
|
|
|
|
|
|
|
|
daemonAPIInstance.CaddyService.Enabled = false |
|
|
|
|
daemonAPIInstance.ThresholdService.Enabled = false |
|
|
|
@ -494,6 +517,7 @@ func main() {
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
postTelemetry("daemon-timed-out-waiting-threshold-and-caddy", daemonTelemetryAccount, daemonTelemetryId, "oof") |
|
|
|
|
done <- true |
|
|
|
|
}() |
|
|
|
|
|
|
|
|
@ -548,6 +572,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 500 internal server error: failed to open log iterator") |
|
|
|
|
go postTelemetry("daemon-logs", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s: %+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -558,6 +583,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
logs, err := child.Joinerate(logIterators, count) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: failed to read log file(s)" |
|
|
|
|
go postTelemetry("daemon-logs", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s: %+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -566,6 +592,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
logBytes, err := json.Marshal(logs) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: json serialization failed" |
|
|
|
|
go postTelemetry("daemon-logs", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s: %+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -590,6 +617,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
fmt.Printf("greenhouse-daemon can't get your account info: greenhouse returned HTTP %d: %s\n", statusCode, errorMessage) |
|
|
|
|
} else { |
|
|
|
|
daemon.TenantInfo = tenantInfo |
|
|
|
|
daemonTelemetryAccount = tenantInfo.EmailAddress |
|
|
|
|
daemon.ConfigService.EmailAddress = tenantInfo.EmailAddress |
|
|
|
|
updateTenantInfoMessage = "success" |
|
|
|
|
} |
|
|
|
@ -608,12 +636,14 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
ApplyConfigStatuses: daemon.ApplyConfigStatuses, |
|
|
|
|
ApplyConfigStatusIndex: daemon.ApplyConfigStatusIndex, |
|
|
|
|
ApplyConfigStatusError: daemon.ApplyConfigStatusError, |
|
|
|
|
DaemonTelemetryID: daemon.TelemetryID, |
|
|
|
|
} |
|
|
|
|
statusBytes, err := json.MarshalIndent(status, "", " ") |
|
|
|
|
|
|
|
|
|
//log.Printf("statusBytes: %s\n\n", statusBytes)
|
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: json serialization failed" |
|
|
|
|
go postTelemetry("daemon-get-status", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
@ -643,6 +673,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
|
|
|
|
|
if tenantInfo.ClientStates[serverName].CurrentState == "ClientConnected" { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 409 conflict, you already have a connected server named '%s'", serverName) |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, errorMessage) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusConflict) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
@ -656,19 +687,23 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
|
|
|
|
|
if err != nil || statusCode != 200 { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon failed to get tenant info: %d %s", statusCode, errorMessage) |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: HTTP %d err: %s\n", errorMessage, statusCode, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, statusCode) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
daemon.TenantInfo = tenantInfo |
|
|
|
|
daemonTelemetryAccount = tenantInfo.EmailAddress |
|
|
|
|
daemon.ConfigService.EmailAddress = tenantInfo.EmailAddress |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, daemonTelemetryAccount) |
|
|
|
|
|
|
|
|
|
// TODO real greenhouse API url
|
|
|
|
|
registerURL := fmt.Sprintf("%s/api/client_config?serverName=%s", daemon.CloudURL, serverName) |
|
|
|
|
configRequest, err := http.NewRequest("POST", registerURL, nil) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error" |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -678,6 +713,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
configResponse, err := daemon.HTTPClient.Do(configRequest) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 503 bad gateway, can't reach greenhouse cloud at %s", registerURL) |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusBadGateway) |
|
|
|
|
return |
|
|
|
@ -687,6 +723,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
"greenhouse-daemon: %d %s, the server at %s returned HTTP %d", |
|
|
|
|
configResponse.StatusCode, configResponse.Status, registerURL, configResponse.StatusCode, |
|
|
|
|
) |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, configResponse.StatusCode) |
|
|
|
|
return |
|
|
|
@ -695,6 +732,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
configBytes, err := ioutil.ReadAll(configResponse.Body) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 503 bad gateway, read error on %s. please try again", registerURL) |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusBadGateway) |
|
|
|
|
return |
|
|
|
@ -704,6 +742,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
err = json.Unmarshal(configBytes, &thresholdConfig) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 500 internal server error, %s did not return json", registerURL) |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -724,6 +763,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
configBytesToWrite, err := json.MarshalIndent(thresholdConfig, "", " ") |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: json serialization failed" |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -731,6 +771,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
err = ioutil.WriteFile(filepath.Join(daemon.DaemonPath, "threshold-config.json"), configBytesToWrite, 0600) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: write threshold config file failed" |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -739,15 +780,16 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
err = daemon.writeDaemonConfigJSON() |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: writeDaemonConfigJSON failed" |
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
go postTelemetry("daemon-register", daemonTelemetryAccount, daemonTelemetryId, "success!!") |
|
|
|
|
responseWriter.Write([]byte("OK")) |
|
|
|
|
|
|
|
|
|
case "/unregister": |
|
|
|
|
|
|
|
|
|
os.Remove(filepath.Join(daemon.DaemonPath, "threshold-config.json")) |
|
|
|
|
os.Remove(filepath.Join(daemon.DaemonPath, "daemon-config.json")) |
|
|
|
|
os.Remove(filepath.Join(daemon.DaemonPath, "daemon-tenant-info.json")) |
|
|
|
@ -758,12 +800,15 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
daemon.Config.APIToken = "" |
|
|
|
|
daemon.Config.ServerName = "" |
|
|
|
|
|
|
|
|
|
go postTelemetry("daemon-unregister", daemonTelemetryAccount, daemonTelemetryId, "success!!") |
|
|
|
|
|
|
|
|
|
responseWriter.Write([]byte("OK")) |
|
|
|
|
|
|
|
|
|
case "/apply_config": |
|
|
|
|
requestBytes, err := ioutil.ReadAll(request.Body) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 apply_config failed: http read error" |
|
|
|
|
go postTelemetry("daemon-apply-config", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -774,7 +819,8 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
var tunnels []GUITunnel |
|
|
|
|
err = json.Unmarshal(requestBytes, &tunnels) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 400 bad request: invalid json: %s", err) |
|
|
|
|
errorMessage := "greenhouse-daemon: 400 bad request: invalid json:" |
|
|
|
|
go postTelemetry("daemon-apply-config", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusBadRequest) |
|
|
|
|
return |
|
|
|
@ -790,6 +836,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
thresholdConfig, caddyConfig, err := daemon.ConfigService.PrepareConfigs(tunnels) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := fmt.Sprintf("greenhouse-daemon: 400 bad request: %s", err) |
|
|
|
|
go postTelemetry("daemon-apply-config", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusBadRequest) |
|
|
|
|
return |
|
|
|
@ -803,16 +850,22 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
err = daemon.writeDaemonConfigJSON() |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: writeDaemonConfigJSON failed" |
|
|
|
|
go postTelemetry("daemon-apply-config", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
go postTelemetry("daemon-apply-config", daemonTelemetryAccount, daemonTelemetryId, "started...") |
|
|
|
|
|
|
|
|
|
completionChannel := make(chan bool) |
|
|
|
|
go daemon.applyConfigAsync(tunnels, thresholdConfig, caddyConfig, completionChannel) |
|
|
|
|
|
|
|
|
|
go (func() { |
|
|
|
|
<-completionChannel |
|
|
|
|
go postTelemetry("daemon-apply-config", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf( |
|
|
|
|
"completed: ApplyConfigStatusIndex: %d, error: '%s'", daemon.ApplyConfigStatusIndex, daemon.ApplyConfigStatusError, |
|
|
|
|
)) |
|
|
|
|
log.Printf("/apply_config releasing ConfigurationMutex lock\n") |
|
|
|
|
daemon.ConfigurationMutex.Unlock() |
|
|
|
|
})() |
|
|
|
@ -823,6 +876,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
}) |
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: netstat.TCPSocks failed" |
|
|
|
|
go postTelemetry("daemon-netstat", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -855,6 +909,7 @@ func (daemon *DaemonAPI) ServeHTTP(responseWriter http.ResponseWriter, request *
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
errorMessage := "greenhouse-daemon: 500 internal server error: json serialization failed" |
|
|
|
|
go postTelemetry("daemon-netstat", daemonTelemetryAccount, daemonTelemetryId, fmt.Sprintf("%s: %s\n", errorMessage, err)) |
|
|
|
|
log.Printf("%s:\n%+v\n", errorMessage, err) |
|
|
|
|
http.Error(responseWriter, errorMessage, http.StatusInternalServerError) |
|
|
|
|
return |
|
|
|
@ -1042,6 +1097,7 @@ func (daemon *DaemonAPI) UpdateTenantInfo(tenantInfo *TenantInfo) (error, int, s
|
|
|
|
|
if err != nil || statusCode != 200 { |
|
|
|
|
return err, statusCode, statusString, nil |
|
|
|
|
} |
|
|
|
|
daemonTelemetryAccount = tenantInfo.EmailAddress |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tenantInfoBytesToWrite, err := json.MarshalIndent(daemon.TenantInfo, "", " ") |
|
|
|
|