Several fixes for the release (#175)

This commit is contained in:
Igor Gov 2021-08-08 10:32:21 +03:00 committed by GitHub
parent 824945141a
commit 7f2021c312
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 68 additions and 47 deletions

View File

@ -1,7 +1,6 @@
package cmd package cmd
import ( import (
"errors"
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/up9inc/mizu/cli/fsUtils" "github.com/up9inc/mizu/cli/fsUtils"
@ -19,8 +18,7 @@ Further info is available at https://github.com/up9inc/mizu`,
} }
mizu.InitLogger() mizu.InitLogger()
if err := mizu.InitConfig(cmd); err != nil { if err := mizu.InitConfig(cmd); err != nil {
mizu.Log.Errorf("Invalid config, Exit %s", err) mizu.Log.Fatal(err)
return errors.New(fmt.Sprintf("%v", err))
} }
return nil return nil

View File

@ -63,7 +63,6 @@ func init() {
tapCmd.Flags().StringArrayP(configStructs.NamespacesTapName, "n", defaultTapConfig.Namespaces, "Namespaces selector") tapCmd.Flags().StringArrayP(configStructs.NamespacesTapName, "n", defaultTapConfig.Namespaces, "Namespaces selector")
tapCmd.Flags().Bool(configStructs.AnalysisTapName, defaultTapConfig.Analysis, "Uploads traffic to UP9 for further analysis (Beta)") tapCmd.Flags().Bool(configStructs.AnalysisTapName, defaultTapConfig.Analysis, "Uploads traffic to UP9 for further analysis (Beta)")
tapCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultTapConfig.AllNamespaces, "Tap all namespaces") tapCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultTapConfig.AllNamespaces, "Tap all namespaces")
tapCmd.Flags().StringP(configStructs.KubeConfigPathTapName, "k", defaultTapConfig.KubeConfigPath, "Path to kube-config file")
tapCmd.Flags().StringArrayP(configStructs.PlainTextFilterRegexesTapName, "r", defaultTapConfig.PlainTextFilterRegexes, "List of regex expressions that are used to filter matching values from text/plain http bodies") tapCmd.Flags().StringArrayP(configStructs.PlainTextFilterRegexesTapName, "r", defaultTapConfig.PlainTextFilterRegexes, "List of regex expressions that are used to filter matching values from text/plain http bodies")
tapCmd.Flags().Bool(configStructs.HideHealthChecksTapName, defaultTapConfig.HideHealthChecks, "hides requests with kube-probe or prometheus user-agent headers") tapCmd.Flags().Bool(configStructs.HideHealthChecksTapName, defaultTapConfig.HideHealthChecks, "hides requests with kube-probe or prometheus user-agent headers")
tapCmd.Flags().Bool(configStructs.DisableRedactionTapName, defaultTapConfig.DisableRedaction, "Disables redaction of potentially sensitive request/response headers and body values") tapCmd.Flags().Bool(configStructs.DisableRedactionTapName, defaultTapConfig.DisableRedaction, "Disables redaction of potentially sensitive request/response headers and body values")

View File

@ -6,6 +6,8 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/up9inc/mizu/cli/fsUtils" "github.com/up9inc/mizu/cli/fsUtils"
"github.com/up9inc/mizu/cli/goUtils"
"github.com/up9inc/mizu/cli/mizu/configStructs"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -56,7 +58,7 @@ func RunMizuTap() {
} }
} }
kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.Tap.KubeConfigPath) kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.KubeConfigPath)
if err != nil { if err != nil {
mizu.Log.Error(err) mizu.Log.Error(err)
return return
@ -101,8 +103,8 @@ func RunMizuTap() {
return return
} }
go createProxyToApiServerPod(ctx, kubernetesProvider, cancel) go goUtils.HandleExcWrapper(createProxyToApiServerPod, ctx, kubernetesProvider, cancel)
go watchPodsForTapping(ctx, kubernetesProvider, targetNamespaces, cancel) go goUtils.HandleExcWrapper(watchPodsForTapping, ctx, kubernetesProvider, targetNamespaces, cancel)
//block until exit signal or error //block until exit signal or error
waitForFinish(ctx, cancel) waitForFinish(ctx, cancel)
@ -399,13 +401,13 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro
} }
case err := <-errorChan: case err := <-errorChan:
mizu.Log.Debugf("Watching pods loop, got error %v, stopping restart tappers debouncer", err) mizu.Log.Debugf("Watching pods loop, got error %v, stopping `restart tappers debouncer`", err)
restartTappersDebouncer.Cancel() restartTappersDebouncer.Cancel()
// TODO: Does this also perform cleanup? // TODO: Does this also perform cleanup?
cancel() cancel()
case <-ctx.Done(): case <-ctx.Done():
mizu.Log.Debugf("Watching pods loop, context done, stopping restart tappers debouncer") mizu.Log.Debugf("Watching pods loop, context done, stopping `restart tappers debouncer`")
restartTappersDebouncer.Cancel() restartTappersDebouncer.Cancel()
return return
} }
@ -465,9 +467,10 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
mizu.Log.Debugf("Watching API Server pod loop, ctx done")
return return
case <-added: case <-added:
mizu.Log.Debugf("Got agent pod added event") mizu.Log.Debugf("Watching API Server pod loop, added")
continue continue
case <-removed: case <-removed:
mizu.Log.Infof("%s removed", mizu.ApiServerPodName) mizu.Log.Infof("%s removed", mizu.ApiServerPodName)
@ -475,16 +478,17 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet
return return
case modifiedPod := <-modified: case modifiedPod := <-modified:
if modifiedPod == nil { if modifiedPod == nil {
mizu.Log.Debugf("Got agent pod modified event, status phase: %v", modifiedPod.Status.Phase) mizu.Log.Debugf("Watching API Server pod loop, modifiedPod with nil")
continue continue
} }
mizu.Log.Debugf("Got agent pod modified event, status phase: %v", modifiedPod.Status.Phase) mizu.Log.Debugf("Watching API Server pod loop, modified: %v", modifiedPod.Status.Phase)
if modifiedPod.Status.Phase == core.PodRunning && !isPodReady { if modifiedPod.Status.Phase == core.PodRunning && !isPodReady {
isPodReady = true isPodReady = true
go func() { go func() {
err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName)
if err != nil { if err != nil {
mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v", errormessage.FormatError(err))) mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v\n"+
"Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName))
cancel() cancel()
} }
}() }()
@ -530,21 +534,15 @@ func requestForAnalysis() {
} }
func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, error) { func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, error) {
mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName) if !mizu.Config.IsNsRestrictedMode() {
if err != nil { err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion)
return false, err if err != nil {
} return false, err
if !mizuRBACExists { }
if !mizu.Config.IsNsRestrictedMode() { } else {
err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion)
if err != nil { if err != nil {
return false, err return false, err
}
} else {
err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion)
if err != nil {
return false, err
}
} }
} }
return true, nil return true, nil

View File

@ -38,6 +38,6 @@ func runMizuView() {
mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.View.GuiPort)) mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.View.GuiPort))
err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName)
if err != nil { if err != nil {
mizu.Log.Infof("Error occured while running k8s proxy %v", err) mizu.Log.Errorf("Error occurred while running k8s proxy %v", err)
} }
} }

View File

@ -18,7 +18,7 @@ func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath strin
} }
if len(pods) == 0 { if len(pods) == 0 {
return fmt.Errorf("no pods found in namespace %s", mizu.Config.MizuResourcesNamespace) return fmt.Errorf("no mizu pods found in namespace %s", mizu.Config.MizuResourcesNamespace)
} }
newZipFile, err := os.Create(filePath) newZipFile, err := os.Create(filePath)
@ -49,7 +49,7 @@ func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath strin
mizu.Log.Infof("Successfully added file %s", mizu.GetConfigFilePath()) mizu.Log.Infof("Successfully added file %s", mizu.GetConfigFilePath())
} }
if err := AddFileToZip(zipWriter, mizu.GetLogFilePath()); err != nil { if err := AddFileToZip(zipWriter, mizu.GetLogFilePath()); err != nil {
mizu.Log.Errorf("Failed write file, %v", err) mizu.Log.Debugf("Failed write file, %v", err)
} else { } else {
mizu.Log.Infof("Successfully added file %s", mizu.GetLogFilePath()) mizu.Log.Infof("Successfully added file %s", mizu.GetLogFilePath())
} }

View File

@ -0,0 +1,25 @@
package goUtils
import (
"github.com/up9inc/mizu/cli/mizu"
"reflect"
"runtime/debug"
)
func HandleExcWrapper(fn interface{}, params ...interface{}) (result []reflect.Value) {
defer func() {
if panicMessage := recover(); panicMessage != nil {
stack := debug.Stack()
mizu.Log.Fatalf("Unhandled panic: %v\n stack: %s", panicMessage, stack)
}
}()
f := reflect.ValueOf(fn)
if f.Type().NumIn() != len(params) {
panic("incorrect number of parameters!")
}
inputs := make([]reflect.Value, len(params))
for k, in := range params {
inputs[k] = reflect.ValueOf(in)
}
return f.Call(inputs)
}

View File

@ -13,17 +13,14 @@ import (
"strconv" "strconv"
"github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/cli/mizu"
"io"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/homedir"
"github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared"
"io"
core "k8s.io/api/core/v1" core "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1" rbac "k8s.io/api/rbac/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors" k8serrors "k8s.io/apimachinery/pkg/api/errors"
resource "k8s.io/apimachinery/pkg/api/resource" resource "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1"
@ -35,9 +32,11 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
_ "k8s.io/client-go/plugin/pkg/client/auth/openstack" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
_ "k8s.io/client-go/tools/portforward" _ "k8s.io/client-go/tools/portforward"
watchtools "k8s.io/client-go/tools/watch" watchtools "k8s.io/client-go/tools/watch"
"k8s.io/client-go/util/homedir"
) )
type Provider struct { type Provider struct {
@ -358,15 +357,15 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string,
}, },
} }
_, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) _, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{})
if err != nil { if err != nil && !k8serrors.IsAlreadyExists(err) {
return err return err
} }
_, err = provider.clientSet.RbacV1().ClusterRoles().Create(ctx, clusterRole, metav1.CreateOptions{}) _, err = provider.clientSet.RbacV1().ClusterRoles().Create(ctx, clusterRole, metav1.CreateOptions{})
if err != nil { if err != nil && !k8serrors.IsAlreadyExists(err) {
return err return err
} }
_, err = provider.clientSet.RbacV1().ClusterRoleBindings().Create(ctx, clusterRoleBinding, metav1.CreateOptions{}) _, err = provider.clientSet.RbacV1().ClusterRoleBindings().Create(ctx, clusterRoleBinding, metav1.CreateOptions{})
if err != nil { if err != nil && !k8serrors.IsAlreadyExists(err) {
return err return err
} }
return nil return nil
@ -412,15 +411,15 @@ func (provider *Provider) CreateMizuRBACNamespaceRestricted(ctx context.Context,
}, },
} }
_, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) _, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{})
if err != nil { if err != nil && !k8serrors.IsAlreadyExists(err) {
return err return err
} }
_, err = provider.clientSet.RbacV1().Roles(namespace).Create(ctx, role, metav1.CreateOptions{}) _, err = provider.clientSet.RbacV1().Roles(namespace).Create(ctx, role, metav1.CreateOptions{})
if err != nil { if err != nil && !k8serrors.IsAlreadyExists(err) {
return err return err
} }
_, err = provider.clientSet.RbacV1().RoleBindings(namespace).Create(ctx, roleBinding, metav1.CreateOptions{}) _, err = provider.clientSet.RbacV1().RoleBindings(namespace).Create(ctx, roleBinding, metav1.CreateOptions{})
if err != nil { if err != nil && !k8serrors.IsAlreadyExists(err) {
return err return err
} }
return nil return nil

View File

@ -2,8 +2,9 @@ package main
import ( import (
"github.com/up9inc/mizu/cli/cmd" "github.com/up9inc/mizu/cli/cmd"
"github.com/up9inc/mizu/cli/goUtils"
) )
func main() { func main() {
cmd.Execute() goUtils.HandleExcWrapper(cmd.Execute)
} }

View File

@ -28,6 +28,7 @@ var allowedSetFlags = []string{
MizuResourcesNamespaceConfigName, MizuResourcesNamespaceConfigName,
TelemetryConfigName, TelemetryConfigName,
DumpLogsConfigName, DumpLogsConfigName,
KubeConfigPathName,
configStructs.AnalysisDestinationTapName, configStructs.AnalysisDestinationTapName,
configStructs.SleepIntervalSecTapName, configStructs.SleepIntervalSecTapName,
} }
@ -51,8 +52,8 @@ func InitConfig(cmd *cobra.Command) error {
} }
if err := mergeConfigFile(); err != nil { if err := mergeConfigFile(); err != nil {
Log.Errorf("Could not load config file, error %v", err) return fmt.Errorf("invalid config %w\n"+
Log.Fatalf("You can regenerate the file using `mizu config -r` or just remove it %v", GetConfigFilePath()) "you can regenerate the file using `mizu config -r` or just remove it %v", err, GetConfigFilePath())
} }
cmd.Flags().Visit(initFlag) cmd.Flags().Visit(initFlag)

View File

@ -11,6 +11,7 @@ const (
MizuResourcesNamespaceConfigName = "mizu-resources-namespace" MizuResourcesNamespaceConfigName = "mizu-resources-namespace"
TelemetryConfigName = "telemetry" TelemetryConfigName = "telemetry"
DumpLogsConfigName = "dump-logs" DumpLogsConfigName = "dump-logs"
KubeConfigPathName = "kube-config-path"
) )
type ConfigStruct struct { type ConfigStruct struct {
@ -22,6 +23,7 @@ type ConfigStruct struct {
MizuResourcesNamespace string `yaml:"mizu-resources-namespace" default:"mizu"` MizuResourcesNamespace string `yaml:"mizu-resources-namespace" default:"mizu"`
Telemetry bool `yaml:"telemetry" default:"true"` Telemetry bool `yaml:"telemetry" default:"true"`
DumpLogs bool `yaml:"dump-logs" default:"false"` DumpLogs bool `yaml:"dump-logs" default:"false"`
KubeConfigPath string `yaml:"kube-config-path" default:""`
} }
func (config *ConfigStruct) SetDefaults() { func (config *ConfigStruct) SetDefaults() {

View File

@ -16,7 +16,6 @@ const (
NamespacesTapName = "namespaces" NamespacesTapName = "namespaces"
AnalysisTapName = "analysis" AnalysisTapName = "analysis"
AllNamespacesTapName = "all-namespaces" AllNamespacesTapName = "all-namespaces"
KubeConfigPathTapName = "kube-config"
PlainTextFilterRegexesTapName = "regex-masking" PlainTextFilterRegexesTapName = "regex-masking"
HideHealthChecksTapName = "hide-healthchecks" HideHealthChecksTapName = "hide-healthchecks"
DisableRedactionTapName = "no-redact" DisableRedactionTapName = "no-redact"
@ -34,7 +33,6 @@ type TapConfig struct {
Namespaces []string `yaml:"namespaces"` Namespaces []string `yaml:"namespaces"`
Analysis bool `yaml:"analysis" default:"false"` Analysis bool `yaml:"analysis" default:"false"`
AllNamespaces bool `yaml:"all-namespaces" default:"false"` AllNamespaces bool `yaml:"all-namespaces" default:"false"`
KubeConfigPath string `yaml:"kube-config"`
PlainTextFilterRegexes []string `yaml:"regex-masking"` PlainTextFilterRegexes []string `yaml:"regex-masking"`
HideHealthChecks bool `yaml:"hide-healthchecks" default:"false"` HideHealthChecks bool `yaml:"hide-healthchecks" default:"false"`
DisableRedaction bool `yaml:"no-redact" default:"false"` DisableRedaction bool `yaml:"no-redact" default:"false"`