Merge branch 'develop'

# Conflicts:
#	acceptanceTests/tap_test.go
#	cli/apiserver/provider.go
#	cli/cmd/common.go
#	cli/cmd/fetch.go
#	cli/cmd/fetchRunner.go
#	cli/cmd/tapRunner.go
#	cli/cmd/viewRunner.go
#	cli/config/config.go
#	cli/mizu/fsUtils/mizuLogsUtils.go
This commit is contained in:
Igor Gov 2021-09-02 12:17:57 +03:00
commit 680ea71958
17 changed files with 135 additions and 23 deletions

View File

@ -71,7 +71,6 @@ func TestTapAndFetch(t *testing.T) {
} }
entries := requestResult.([]interface{}) entries := requestResult.([]interface{})
if len(entries) == 0 { if len(entries) == 0 {
return fmt.Errorf("unexpected entries result - Expected more than 0 entries") return fmt.Errorf("unexpected entries result - Expected more than 0 entries")
} }
@ -523,6 +522,10 @@ func TestTapRedact(t *testing.T) {
} }
entries := requestResult.([]interface{}) entries := requestResult.([]interface{})
if len(entries) == 0 {
return fmt.Errorf("unexpected entries result - Expected more than 0 entries")
}
firstEntry := entries[0].(map[string]interface{}) firstEntry := entries[0].(map[string]interface{})
entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"]) entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"])
@ -625,6 +628,10 @@ func TestTapNoRedact(t *testing.T) {
} }
entries := requestResult.([]interface{}) entries := requestResult.([]interface{})
if len(entries) == 0 {
return fmt.Errorf("unexpected entries result - Expected more than 0 entries")
}
firstEntry := entries[0].(map[string]interface{}) firstEntry := entries[0].(map[string]interface{})
entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"]) entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"])
@ -727,6 +734,10 @@ func TestTapRegexMasking(t *testing.T) {
} }
entries := requestResult.([]interface{}) entries := requestResult.([]interface{})
if len(entries) == 0 {
return fmt.Errorf("unexpected entries result - Expected more than 0 entries")
}
firstEntry := entries[0].(map[string]interface{}) firstEntry := entries[0].(map[string]interface{})
entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"]) entryUrl := fmt.Sprintf("%v/api/entries/%v", apiServerUrl, firstEntry["id"])

View File

@ -107,6 +107,7 @@ func hostApi(socketHarOutputChannel chan<- *tap.OutputChannelItem) {
SocketHarOutChannel: socketHarOutputChannel, SocketHarOutChannel: socketHarOutputChannel,
} }
app.Use(DisableRootStaticCache())
app.Use(static.ServeRoot("/", "./site")) app.Use(static.ServeRoot("/", "./site"))
app.Use(CORSMiddleware()) // This has to be called after the static middleware, does not work if its called before 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) 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 { func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Origin", "*")

View File

@ -5,6 +5,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/up9inc/mizu/cli/config"
"github.com/up9inc/mizu/cli/logger" "github.com/up9inc/mizu/cli/logger"
"github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/cli/uiUtils"
"github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared"
@ -18,18 +19,27 @@ import (
type apiServerProvider struct { type apiServerProvider struct {
url string url string
isReady bool 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) healthUrl := fmt.Sprintf("%s/", url)
retriesLeft := retries retriesLeft := provider.retries
for retriesLeft > 0 { for retriesLeft > 0 {
if response, err := http.Get(healthUrl); err != nil { if response, err := http.Get(healthUrl); err != nil {
logger.Log.Debugf("[ERROR] failed connecting to api server %v", err) logger.Log.Debugf("[ERROR] failed connecting to api server %v", err)
} else if response.StatusCode != 200 { } 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 { } else {
logger.Log.Debugf("connection test to api server passed successfully") logger.Log.Debugf("connection test to api server passed successfully")
break break
@ -40,7 +50,7 @@ func (provider *apiServerProvider) InitAndTestConnection(url string, retries int
if retriesLeft == 0 { if retriesLeft == 0 {
provider.isReady = false 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.url = url
provider.isReady = true provider.isReady = true

View File

@ -26,6 +26,8 @@ func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, cancel
"Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName)) "Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName))
cancel() cancel()
} }
logger.Log.Debugf("proxy ended")
} }
func waitForFinish(ctx context.Context, cancel context.CancelFunc) { func waitForFinish(ctx context.Context, cancel context.CancelFunc) {

View File

@ -18,7 +18,7 @@ var fetchCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
go telemetry.ReportRun("fetch", config.Config.Fetch) 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") logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, make sure one running")
return nil return nil
} }

View File

@ -9,7 +9,7 @@ import (
) )
func RunMizuFetch() { 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") logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, check logs")
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/up9inc/mizu/cli/mizu/fsUtils" "github.com/up9inc/mizu/cli/mizu/fsUtils"
"github.com/up9inc/mizu/cli/mizu/version" "github.com/up9inc/mizu/cli/mizu/version"
"github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/cli/uiUtils"
"time"
) )
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
@ -34,10 +35,13 @@ func init() {
} }
func printNewVersionIfNeeded(versionChan chan string) { func printNewVersionIfNeeded(versionChan chan string) {
versionMsg := <-versionChan select {
case versionMsg := <-versionChan:
if versionMsg != "" { if versionMsg != "" {
logger.Log.Infof(uiUtils.Yellow, versionMsg) logger.Log.Infof(uiUtils.Yellow, versionMsg)
} }
case <-time.After(2 * time.Second):
}
} }
// Execute adds all child commands to the root command and sets flags appropriately. // Execute adds all child commands to the root command and sets flags appropriately.

View File

@ -497,7 +497,7 @@ func watchApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provi
isPodReady = true isPodReady = true
go startProxyReportErrorIfAny(kubernetesProvider, cancel) 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") logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, check logs")
cancel() cancel()
break break

View File

@ -43,7 +43,7 @@ func runMizuView() {
logger.Log.Infof("Establishing connection to k8s cluster...") logger.Log.Infof("Establishing connection to k8s cluster...")
go startProxyReportErrorIfAny(kubernetesProvider, cancel) 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") logger.Log.Errorf(uiUtils.Error, "Couldn't connect to API server, check logs")
return return
} }

View File

@ -37,12 +37,14 @@ func InitConfig(cmd *cobra.Command) error {
return err return err
} }
configFilePath := cmd.Flags().Lookup(ConfigFilePathCommandName).Value.String() configFilePathFlag := cmd.Flags().Lookup(ConfigFilePathCommandName)
configFilePath := configFilePathFlag.Value.String()
if err := mergeConfigFile(configFilePath); err != nil { if err := mergeConfigFile(configFilePath); err != nil {
if configFilePathFlag.Changed || !os.IsNotExist(err) {
return fmt.Errorf("invalid config, %w\n"+ return fmt.Errorf("invalid config, %w\n"+
"you can regenerate the file by removing it (%v) and using `mizu config -r`", err, configFilePath) "you can regenerate the file by removing it (%v) and using `mizu config -r`", err, configFilePath)
} }
}
cmd.Flags().Visit(initFlag) cmd.Flags().Visit(initFlag)
@ -67,7 +69,7 @@ func GetConfigWithDefaults() (string, error) {
func mergeConfigFile(configFilePath string) error { func mergeConfigFile(configFilePath string) error {
reader, openErr := os.Open(configFilePath) reader, openErr := os.Open(configFilePath)
if openErr != nil { if openErr != nil {
return nil return openErr
} }
buf, readErr := ioutil.ReadAll(reader) buf, readErr := ioutil.ReadAll(reader)

24
cli/config/envConfig.go Normal file
View File

@ -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
}

View File

@ -739,6 +739,16 @@ func (provider *Provider) GetPodLogs(namespace string, podName string, ctx conte
return str, nil 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) { func getClientSet(config *restclient.Config) (*kubernetes.Clientset, error) {
clientSet, err := kubernetes.NewForConfig(config) clientSet, err := kubernetes.NewForConfig(config)
if err != nil { if err != nil {

View File

@ -39,6 +39,7 @@ func StartProxy(kubernetesProvider *Provider, mizuPort uint16, mizuNamespace str
server := http.Server{ server := http.Server{
Handler: mux, Handler: mux,
} }
return server.Serve(l) return server.Serve(l)
} }

View File

@ -39,22 +39,39 @@ func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath strin
} else { } else {
logger.Log.Debugf("Successfully read log length %d for pod: %s.%s", len(logs), pod.Namespace, pod.Name) 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 { if err := AddStrToZip(zipWriter, logs, fmt.Sprintf("%s.%s.log", pod.Namespace, pod.Name)); err != nil {
logger.Log.Errorf("Failed write logs, %v", err) logger.Log.Errorf("Failed write logs, %v", err)
} else { } else {
logger.Log.Debugf("Successfully added log length %d from pod: %s.%s", len(logs), pod.Namespace, pod.Name) 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 { if err := AddFileToZip(zipWriter, config.Config.ConfigFilePath); err != nil {
logger.Log.Debugf("Failed write file, %v", err) logger.Log.Debugf("Failed write file, %v", err)
} else { } else {
logger.Log.Debugf("Successfully added file %s", config.Config.ConfigFilePath) logger.Log.Debugf("Successfully added file %s", config.Config.ConfigFilePath)
} }
if err := AddFileToZip(zipWriter, logger.GetLogFilePath()); err != nil { if err := AddFileToZip(zipWriter, logger.GetLogFilePath()); err != nil {
logger.Log.Debugf("Failed write file, %v", err) logger.Log.Debugf("Failed write file, %v", err)
} else { } else {
logger.Log.Debugf("Successfully added file %s", logger.GetLogFilePath()) 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) logger.Log.Infof("You can find the zip file with all logs in %s\n", filePath)
return nil return nil
} }

View File

@ -37,6 +37,7 @@ func CheckNewerVersion(versionChan chan string) {
latestRelease, _, err := client.Repositories.GetLatestRelease(context.Background(), "up9inc", "mizu") latestRelease, _, err := client.Repositories.GetLatestRelease(context.Background(), "up9inc", "mizu")
if err != nil { if err != nil {
logger.Log.Debugf("[ERROR] Failed to get latest release") logger.Log.Debugf("[ERROR] Failed to get latest release")
versionChan <- ""
return return
} }
@ -49,12 +50,14 @@ func CheckNewerVersion(versionChan chan string) {
} }
if versionFileUrl == "" { if versionFileUrl == "" {
logger.Log.Debugf("[ERROR] Version file not found in the latest release") logger.Log.Debugf("[ERROR] Version file not found in the latest release")
versionChan <- ""
return return
} }
res, err := http.Get(versionFileUrl) res, err := http.Get(versionFileUrl)
if err != nil { if err != nil {
logger.Log.Debugf("[ERROR] Failed to get the version file %v", err) logger.Log.Debugf("[ERROR] Failed to get the version file %v", err)
versionChan <- ""
return return
} }
@ -62,6 +65,7 @@ func CheckNewerVersion(versionChan chan string) {
res.Body.Close() res.Body.Close()
if err != nil { if err != nil {
logger.Log.Debugf("[ERROR] Failed to read the version file -> %v", err) logger.Log.Debugf("[ERROR] Failed to read the version file -> %v", err)
versionChan <- ""
return return
} }
gitHubVersion := string(data) gitHubVersion := string(data)
@ -73,6 +77,7 @@ func CheckNewerVersion(versionChan chan string) {
if gitHubVersionSemVer.GreaterThan(currentSemVer) { if gitHubVersionSemVer.GreaterThan(currentSemVer) {
versionChan <- fmt.Sprintf("Update available! %v -> %v (%v)", mizu.SemVer, gitHubVersion, *latestRelease.HTMLURL) versionChan <- fmt.Sprintf("Update available! %v -> %v (%v)", mizu.SemVer, gitHubVersion, *latestRelease.HTMLURL)
} } else {
versionChan <- "" versionChan <- ""
} }
}

View File

@ -23,3 +23,16 @@
font-size: 11px font-size: 11px
font-weight: bold font-weight: bold
color: $light-blue-color color: $light-blue-color
.httpsDomains
display: none
margin: 0
padding: 0
list-style: none
.customWarningStyle
&:hover
overflow-y: scroll
height: 85px
.httpsDomains
display: block

View File

@ -119,8 +119,9 @@ const App = () => {
</div> </div>
<TrafficPage setAnalyzeStatus={setAnalyzeStatus} onTLSDetected={onTLSDetected}/> <TrafficPage setAnalyzeStatus={setAnalyzeStatus} onTLSDetected={onTLSDetected}/>
<Snackbar open={showTLSWarning && !userDismissedTLSWarning}> <Snackbar open={showTLSWarning && !userDismissedTLSWarning}>
<MuiAlert elevation={6} variant="filled" onClose={() => setUserDismissedTLSWarning(true)} severity="warning"> <MuiAlert classes={{ filledWarning: 'customWarningStyle' }} elevation={6} variant="filled" onClose={() => setUserDismissedTLSWarning(true)} severity="warning">
Mizu is detecting TLS traffic{addressesWithTLS.size ? ` (directed to ${Array.from(addressesWithTLS).join(", ")})` : ''}, this type of traffic will not be displayed. Mizu is detecting TLS traffic, this type of traffic will not be displayed.
{addressesWithTLS.size > 0 && <ul className="httpsDomains"> {Array.from(addressesWithTLS, address => <li>{address}</li>)} </ul>}
</MuiAlert> </MuiAlert>
</Snackbar> </Snackbar>
</div> </div>