diff --git a/.gitignore b/.gitignore index af131c4b7..1aaa2746e 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,3 @@ Thumbs.db # Test reports *-report.txt - -# hive-ui -hive-ui/certs/ diff --git a/CLAUDE.md b/CLAUDE.md index e49769281..fff26cd53 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -167,7 +167,7 @@ discovery.services # Service registration ### Go Module Structure All Go projects use: -- Go 1.23+ with module mode +- Go 1.25+ with module mode - Local replace directives for cross-component development - Standard build flags: `-ldflags "-s -w"` for optimized binaries - Test environment variable: `LOG_IGNORE=1` to suppress logs during testing @@ -211,4 +211,4 @@ For major feature development and architectural changes, refer to `HIVE_DEVELOPM - Development environment automation plans - Testing and validation frameworks -When implementing new AWS services or enhancing existing functionality, follow the structured approach outlined in the development plan. \ No newline at end of file +When implementing new AWS services or enhancing existing functionality, follow the structured approach outlined in the development plan. diff --git a/hive-ui/README.md b/hive-ui/README.md index ebdc577a6..06b1223c7 100644 --- a/hive-ui/README.md +++ b/hive-ui/README.md @@ -35,21 +35,9 @@ Full-stack application for managing Hive AWS compatible products (EC2, S3) 4. **Accept Certs In Browser** - Setup and run hive server. See [https://github.com/mulgadc/hive/blob/main/INSTALL.md](https://github.com/mulgadc/hive/blob/main/INSTALL.md) for installation documentation to setup a Hive cluster or single node for development purposes. + If you have added the CA to your machine you do not need to do this. But if you are sshd into a hive machine and want to view the ui, simply go to `https://localhost:9999` and `https://localhost:8443` and accept the certificates. - Go to `https://localhost:9999` and `https://localhost:8443` and accept the certificates - - TODO: Tutorial on creating certificate authority and accepting generated certs as trusted. - -5. **Generate Certs** - ```sh - openssl req -x509 -out certs/server.crt -keyout certs/server.key \ - -newkey rsa:2048 -nodes -sha256 \ - -subj '/CN=localhost' -extensions EXT -config <( \ - printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") - ``` - -6. **Launch Server** +5. **Launch Server** For production, build the static assets and launch the `go` webservice for serving traffic: @@ -64,6 +52,6 @@ Full-stack application for managing Hive AWS compatible products (EC2, S3) pnpm dev ``` -7. **Visit WebUI** +6. **Visit WebUI** - View [https://localhost:3000](https://localhost:3000/) in your browser to continue. + View [https://localhost:3000](https://localhost:3000) in your browser to continue. diff --git a/hive-ui/webserver/main.go b/hive-ui/webserver/main.go index ce1868e76..a7ea1bc47 100644 --- a/hive-ui/webserver/main.go +++ b/hive-ui/webserver/main.go @@ -1,7 +1,6 @@ package main import ( - "log" "log/slog" "net/http" "os" @@ -19,13 +18,34 @@ func main() { // Get the project root (current directory when run via make) projectRoot, err := os.Getwd() if err != nil { - log.Fatal("Failed to get project root:", err) + slog.Error("Failed to get project root:", "error", err) + os.Exit(1) } // Check if dist directory exists distDir := filepath.Join(projectRoot, "frontend", "dist") if _, err := os.Stat(distDir); os.IsNotExist(err) { - log.Fatalf("Frontend dist directory not found: %s", distDir) + slog.Error("Frontend dist directory not found:", "error", err) + os.Exit(1) + } + + // Get home directory for certificate files + homeDir, err := os.UserHomeDir() + if err != nil { + slog.Error("Failed to get home directory:", "error", err) + os.Exit(1) + } + certFile := filepath.Join(homeDir, "hive", "config", "server.pem") + keyFile := filepath.Join(homeDir, "hive", "config", "server.key") + + // Check if certificates exist + if _, err := os.Stat(certFile); os.IsNotExist(err) { + slog.Error("Certificate file not found:", "error", err) + os.Exit(1) + } + if _, err := os.Stat(keyFile); os.IsNotExist(err) { + slog.Error("Key file not found:", "error", err) + os.Exit(1) } // Serve static files @@ -53,17 +73,6 @@ func main() { // Wrap handler with security headers and gzip compression http.Handle("/", securityHeadersMiddleware(gzipMiddleware(handler))) - certFile := filepath.Join(projectRoot, "certs", "server.crt") - keyFile := filepath.Join(projectRoot, "certs", "server.key") - - // Check if certificates exist - if _, err := os.Stat(certFile); os.IsNotExist(err) { - log.Fatalf("Certificate file not found: %s", certFile) - } - if _, err := os.Stat(keyFile); os.IsNotExist(err) { - log.Fatalf("Key file not found: %s", keyFile) - } - port := ":3000" server := &http.Server{ @@ -75,7 +84,10 @@ func main() { } slog.Info("Starting server with HTTPS", "port", port) - log.Fatal(server.ListenAndServeTLS(certFile, keyFile)) + if err := server.ListenAndServeTLS(certFile, keyFile); err != nil { + slog.Error("Failed to start server:", "error", err) + os.Exit(1) + } } func securityHeadersMiddleware(next http.Handler) http.Handler { @@ -100,7 +112,8 @@ func gzipMiddleware(next http.Handler) http.Handler { "text/plain", })) if err != nil { - log.Fatal("Failed to create gzip middleware:", err) + slog.Warn("Failed to create gzip middleware, serving uncompressed:", "error", err) + return next } return g(next) }