diff --git a/acceptanceTests/tap_test.go b/acceptanceTests/tap_test.go index 8d921ed1f..e4f8888df 100644 --- a/acceptanceTests/tap_test.go +++ b/acceptanceTests/tap_test.go @@ -71,7 +71,6 @@ func TestTapAndFetch(t *testing.T) { } entries := requestResult.([]interface{}) - if len(entries) == 0 { return fmt.Errorf("unexpected entries result - Expected more than 0 entries") } @@ -523,6 +522,10 @@ func TestTapRedact(t *testing.T) { } entries := requestResult.([]interface{}) + if len(entries) == 0 { + return fmt.Errorf("unexpected entries result - Expected more than 0 entries") + } + firstEntry := entries[0].(map[string]interface{}) entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"]) @@ -625,6 +628,10 @@ func TestTapNoRedact(t *testing.T) { } entries := requestResult.([]interface{}) + if len(entries) == 0 { + return fmt.Errorf("unexpected entries result - Expected more than 0 entries") + } + firstEntry := entries[0].(map[string]interface{}) entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"]) @@ -727,6 +734,10 @@ func TestTapRegexMasking(t *testing.T) { } entries := requestResult.([]interface{}) + if len(entries) == 0 { + return fmt.Errorf("unexpected entries result - Expected more than 0 entries") + } + firstEntry := entries[0].(map[string]interface{}) entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"]) diff --git a/agent/main.go b/agent/main.go index 8f0ffd4d6..8aff329c3 100644 --- a/agent/main.go +++ b/agent/main.go @@ -107,6 +107,7 @@ func hostApi(socketHarOutputChannel chan<- *tap.OutputChannelItem) { SocketHarOutChannel: socketHarOutputChannel, } + app.Use(DisableRootStaticCache()) app.Use(static.ServeRoot("/", "./site")) app.Use(CORSMiddleware()) // This has to be called after the static middleware, does not work if its called before @@ -119,6 +120,17 @@ func hostApi(socketHarOutputChannel chan<- *tap.OutputChannelItem) { utils.StartServer(app) } +func DisableRootStaticCache() gin.HandlerFunc { + return func(c *gin.Context) { + if c.Request.RequestURI == "/" { + // Disable cache only for the main static route + c.Writer.Header().Set("Cache-Control", "no-store") + } + + c.Next() + } +} + func CORSMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") diff --git a/cli/apiserver/provider.go b/cli/apiserver/provider.go index e10c7b130..5b8ca44cf 100644 --- a/cli/apiserver/provider.go +++ b/cli/apiserver/provider.go @@ -5,6 +5,7 @@ import ( "bytes" "encoding/json" "fmt" + "github.com/up9inc/mizu/cli/config" "github.com/up9inc/mizu/cli/logger" "github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/shared" @@ -18,18 +19,27 @@ import ( type apiServerProvider struct { url string isReady bool + retries int } -var Provider = apiServerProvider{} +var Provider = apiServerProvider{retries: config.GetIntEnvConfig(config.ApiServerRetries, 20)} -func (provider *apiServerProvider) InitAndTestConnection(url string, retries int) error { +func (provider *apiServerProvider) InitAndTestConnection(url string) error { healthUrl := fmt.Sprintf("%s/", url) - retriesLeft := retries + retriesLeft := provider.retries for retriesLeft > 0 { if response, err := http.Get(healthUrl); err != nil { logger.Log.Debugf("[ERROR] failed connecting to api server %v", err) } else if response.StatusCode != 200 { - logger.Log.Debugf("can't connect to api server yet, response status code %v", response.StatusCode) + responseBody := "" + data, readErr := ioutil.ReadAll(response.Body) + if readErr == nil { + responseBody = string(data) + } + + logger.Log.Debugf("can't connect to api server yet, response status code: %v, body: %v", response.StatusCode, responseBody) + + response.Body.Close() } else { logger.Log.Debugf("connection test to api server passed successfully") break @@ -40,7 +50,7 @@ func (provider *apiServerProvider) InitAndTestConnection(url string, retries int if retriesLeft == 0 { provider.isReady = false - return fmt.Errorf("couldn't reach the api server after %v retries", retries) + return fmt.Errorf("couldn't reach the api server after %v retries", provider.retries) } provider.url = url provider.isReady = true diff --git a/cli/cmd/common.go b/cli/cmd/common.go index 907663b2c..1f09c6ace 100644 --- a/cli/cmd/common.go +++ b/cli/cmd/common.go @@ -26,6 +26,8 @@ func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, cancel "Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName)) cancel() } + + logger.Log.Debugf("proxy ended") } func waitForFinish(ctx context.Context, cancel context.CancelFunc) { diff --git a/cli/cmd/fetch.go b/cli/cmd/fetch.go index dfddc350d..15d124726 100644 --- a/cli/cmd/fetch.go +++ b/cli/cmd/fetch.go @@ -18,7 +18,7 @@ var fetchCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { go telemetry.ReportRun("fetch", config.Config.Fetch) - if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl(), 1); err != nil { + if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl()); err != nil { logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, make sure one running") return nil } diff --git a/cli/cmd/fetchRunner.go b/cli/cmd/fetchRunner.go index aeff496af..0b539244a 100644 --- a/cli/cmd/fetchRunner.go +++ b/cli/cmd/fetchRunner.go @@ -9,7 +9,7 @@ import ( ) func RunMizuFetch() { - if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl(), 5); err != nil { + if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl()); err != nil { logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, check logs") } diff --git a/cli/cmd/root.go b/cli/cmd/root.go index d14c54acf..39729b6f5 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -10,6 +10,7 @@ import ( "github.com/up9inc/mizu/cli/mizu/fsUtils" "github.com/up9inc/mizu/cli/mizu/version" "github.com/up9inc/mizu/cli/uiUtils" + "time" ) var rootCmd = &cobra.Command{ @@ -34,9 +35,12 @@ func init() { } func printNewVersionIfNeeded(versionChan chan string) { - versionMsg := <-versionChan - if versionMsg != "" { - logger.Log.Infof(uiUtils.Yellow, versionMsg) + select { + case versionMsg := <-versionChan: + if versionMsg != "" { + logger.Log.Infof(uiUtils.Yellow, versionMsg) + } + case <-time.After(2 * time.Second): } } diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 5c44b9348..b1ce78cb8 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -497,7 +497,7 @@ func watchApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provi isPodReady = true go startProxyReportErrorIfAny(kubernetesProvider, cancel) - if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl(), 20); err != nil { + if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl()); err != nil { logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, check logs") cancel() break diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index 4ef1d6dfa..69bd2a27c 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -43,7 +43,7 @@ func runMizuView() { logger.Log.Infof("Establishing connection to k8s cluster...") go startProxyReportErrorIfAny(kubernetesProvider, cancel) - if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl(), 10); err != nil { + if err := apiserver.Provider.InitAndTestConnection(GetApiServerUrl()); err != nil { logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, check logs") return } diff --git a/cli/config/config.go b/cli/config/config.go index ab6332b51..b75e79cb8 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -37,11 +37,13 @@ func InitConfig(cmd *cobra.Command) error { return err } - configFilePath := cmd.Flags().Lookup(ConfigFilePathCommandName).Value.String() - + configFilePathFlag := cmd.Flags().Lookup(ConfigFilePathCommandName) + configFilePath := configFilePathFlag.Value.String() if err := mergeConfigFile(configFilePath); err != nil { - return fmt.Errorf("invalid config, %w\n"+ - "you can regenerate the file by removing it (%v) and using `mizu config -r`", err, configFilePath) + if configFilePathFlag.Changed || !os.IsNotExist(err) { + return fmt.Errorf("invalid config, %w\n"+ + "you can regenerate the file by removing it (%v) and using `mizu config -r`", err, configFilePath) + } } cmd.Flags().Visit(initFlag) @@ -67,7 +69,7 @@ func GetConfigWithDefaults() (string, error) { func mergeConfigFile(configFilePath string) error { reader, openErr := os.Open(configFilePath) if openErr != nil { - return nil + return openErr } buf, readErr := ioutil.ReadAll(reader) diff --git a/cli/config/envConfig.go b/cli/config/envConfig.go new file mode 100644 index 000000000..78f91e00b --- /dev/null +++ b/cli/config/envConfig.go @@ -0,0 +1,24 @@ +package config + +import ( + "os" + "strconv" +) + +const ( + ApiServerRetries = "API_SERVER_RETRIES" +) + +func GetIntEnvConfig(key string, defaultValue int) int { + value := os.Getenv(key) + if value == "" { + return defaultValue + } + + intValue, err := strconv.Atoi(value) + if err != nil { + return defaultValue + } + + return intValue +} diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 1603b1307..486bf1377 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -739,6 +739,16 @@ func (provider *Provider) GetPodLogs(namespace string, podName string, ctx conte return str, nil } +func (provider *Provider) GetNamespaceEvents(namespace string, ctx context.Context) (string, error) { + eventsOpts := metav1.ListOptions{} + eventList, err := provider.clientSet.CoreV1().Events(namespace).List(ctx, eventsOpts) + if err != nil { + return "", fmt.Errorf("error getting events on ns: %s, %w", namespace, err) + } + + return eventList.String(), nil +} + func getClientSet(config *restclient.Config) (*kubernetes.Clientset, error) { clientSet, err := kubernetes.NewForConfig(config) if err != nil { diff --git a/cli/kubernetes/proxy.go b/cli/kubernetes/proxy.go index 44397bdc4..8489f0b4a 100644 --- a/cli/kubernetes/proxy.go +++ b/cli/kubernetes/proxy.go @@ -39,6 +39,7 @@ func StartProxy(kubernetesProvider *Provider, mizuPort uint16, mizuNamespace str server := http.Server{ Handler: mux, } + return server.Serve(l) } diff --git a/cli/mizu/fsUtils/mizuLogsUtils.go b/cli/mizu/fsUtils/mizuLogsUtils.go index 8cfc9524d..54ab05d28 100644 --- a/cli/mizu/fsUtils/mizuLogsUtils.go +++ b/cli/mizu/fsUtils/mizuLogsUtils.go @@ -39,22 +39,39 @@ func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath strin } else { logger.Log.Debugf("Successfully read log length %d for pod: %s.%s", len(logs), pod.Namespace, pod.Name) } + if err := AddStrToZip(zipWriter, logs, fmt.Sprintf("%s.%s.log", pod.Namespace, pod.Name)); err != nil { logger.Log.Errorf("Failed write logs, %v", err) } else { logger.Log.Debugf("Successfully added log length %d from pod: %s.%s", len(logs), pod.Namespace, pod.Name) } } + + events, err := provider.GetNamespaceEvents(config.Config.MizuResourcesNamespace, ctx) + if err != nil { + logger.Log.Debugf("Failed to get k8b events, %v", err) + } else { + logger.Log.Debugf("Successfully read events for k8b namespace: %s", config.Config.MizuResourcesNamespace) + } + + if err := AddStrToZip(zipWriter, events, fmt.Sprintf("%s_events.log", config.Config.MizuResourcesNamespace)); err != nil { + logger.Log.Debugf("Failed write logs, %v", err) + } else { + logger.Log.Debugf("Successfully added events for k8b namespace: %s", config.Config.MizuResourcesNamespace) + } + if err := AddFileToZip(zipWriter, config.Config.ConfigFilePath); err != nil { logger.Log.Debugf("Failed write file, %v", err) } else { logger.Log.Debugf("Successfully added file %s", config.Config.ConfigFilePath) } + if err := AddFileToZip(zipWriter, logger.GetLogFilePath()); err != nil { logger.Log.Debugf("Failed write file, %v", err) } else { logger.Log.Debugf("Successfully added file %s", logger.GetLogFilePath()) } + logger.Log.Infof("You can find the zip file with all logs in %s\n", filePath) return nil } diff --git a/cli/mizu/version/versionCheck.go b/cli/mizu/version/versionCheck.go index f9f4d2fc5..2c662b2cb 100644 --- a/cli/mizu/version/versionCheck.go +++ b/cli/mizu/version/versionCheck.go @@ -37,6 +37,7 @@ func CheckNewerVersion(versionChan chan string) { latestRelease, _, err := client.Repositories.GetLatestRelease(context.Background(), "up9inc", "mizu") if err != nil { logger.Log.Debugf("[ERROR] Failed to get latest release") + versionChan <- "" return } @@ -49,12 +50,14 @@ func CheckNewerVersion(versionChan chan string) { } if versionFileUrl == "" { logger.Log.Debugf("[ERROR] Version file not found in the latest release") + versionChan <- "" return } res, err := http.Get(versionFileUrl) if err != nil { logger.Log.Debugf("[ERROR] Failed to get the version file %v", err) + versionChan <- "" return } @@ -62,6 +65,7 @@ func CheckNewerVersion(versionChan chan string) { res.Body.Close() if err != nil { logger.Log.Debugf("[ERROR] Failed to read the version file -> %v", err) + versionChan <- "" return } gitHubVersion := string(data) @@ -73,6 +77,7 @@ func CheckNewerVersion(versionChan chan string) { if gitHubVersionSemVer.GreaterThan(currentSemVer) { versionChan <- fmt.Sprintf("Update available! %v -> %v (%v)", mizu.SemVer, gitHubVersion, *latestRelease.HTMLURL) + } else { + versionChan <- "" } - versionChan <- "" } diff --git a/ui/src/App.sass b/ui/src/App.sass index 0b409a236..7ef640155 100644 --- a/ui/src/App.sass +++ b/ui/src/App.sass @@ -22,4 +22,17 @@ margin-left: 10px font-size: 11px font-weight: bold - color: $light-blue-color \ No newline at end of file + color: $light-blue-color + + .httpsDomains + display: none + margin: 0 + padding: 0 + list-style: none + + .customWarningStyle + &:hover + overflow-y: scroll + height: 85px + .httpsDomains + display: block diff --git a/ui/src/App.tsx b/ui/src/App.tsx index fa5b8153c..3ea758f8d 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -92,7 +92,7 @@ const App = () => { - + return (