💥 Rename tap command to deploy

This commit is contained in:
M. Mert Yildiran 2022-11-29 06:54:05 +03:00
parent 5e579ddfb7
commit ae278526ab
No known key found for this signature in database
GPG Key ID: DA5D6DCBB758A461
8 changed files with 92 additions and 92 deletions

View File

@ -22,7 +22,7 @@ import (
) )
func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, ctx context.Context, cancel context.CancelFunc, serviceName string, srcPort uint16, dstPort uint16, healthCheck string) { func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, ctx context.Context, cancel context.CancelFunc, serviceName string, srcPort uint16, dstPort uint16, healthCheck string) {
httpServer, err := kubernetes.StartProxy(kubernetesProvider, config.Config.Tap.ProxyHost, srcPort, dstPort, config.Config.ResourcesNamespace, serviceName, cancel) httpServer, err := kubernetes.StartProxy(kubernetesProvider, config.Config.Deploy.ProxyHost, srcPort, dstPort, config.Config.ResourcesNamespace, serviceName, cancel)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(errormessage.FormatError(err)). Err(errormessage.FormatError(err)).
@ -115,7 +115,7 @@ func dumpLogsIfNeeded(ctx context.Context, kubernetesProvider *kubernetes.Provid
} }
} }
func getSerializedTapConfig(conf *models.Config) (string, error) { func getSerializedDeployConfig(conf *models.Config) (string, error) {
serializedConfig, err := json.Marshal(conf) serializedConfig, err := json.Marshal(conf)
if err != nil { if err != nil {
return "", err return "", err

60
cmd/deploy.go Normal file
View File

@ -0,0 +1,60 @@
package cmd
import (
"errors"
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/kubeshark/kubeshark/errormessage"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
var deployCmd = &cobra.Command{
Use: "deploy [POD REGEX]",
Short: "Deploy Kubeshark into your K8s cluster.",
Long: `Deploy Kubeshark into your K8s cluster to gain visibility.`,
RunE: func(cmd *cobra.Command, args []string) error {
RunKubesharkTap()
return nil
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 1 {
config.Config.Deploy.PodRegexStr = args[0]
} else if len(args) > 1 {
return errors.New("unexpected number of arguments")
}
if err := config.Config.Deploy.Validate(); err != nil {
return errormessage.FormatError(err)
}
log.Info().
Str("limit", config.Config.Deploy.HumanMaxEntriesDBSize).
Msg("Kubeshark will store the traffic up to a limit. Oldest entries will be removed once the limit is reached.")
return nil
},
}
func init() {
rootCmd.AddCommand(deployCmd)
defaultDeployConfig := configStructs.DeployConfig{}
if err := defaults.Set(&defaultDeployConfig); err != nil {
log.Debug().Err(err).Send()
}
deployCmd.Flags().Uint16P(configStructs.GuiPortTapName, "p", defaultDeployConfig.GuiPort, "Provide a custom port for the web interface webserver")
deployCmd.Flags().StringSliceP(configStructs.NamespacesTapName, "n", defaultDeployConfig.Namespaces, "Namespaces selector")
deployCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultDeployConfig.AllNamespaces, "Tap all namespaces")
deployCmd.Flags().Bool(configStructs.EnableRedactionTapName, defaultDeployConfig.EnableRedaction, "Enables redaction of potentially sensitive request/response headers and body values")
deployCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultDeployConfig.HumanMaxEntriesDBSize, "Override the default max entries db size")
deployCmd.Flags().String(configStructs.InsertionFilterName, defaultDeployConfig.InsertionFilter, "Set the insertion filter. Accepts string or a file path.")
deployCmd.Flags().Bool(configStructs.DryRunTapName, defaultDeployConfig.DryRun, "Preview of all pods matching the regex, without tapping them")
deployCmd.Flags().Bool(configStructs.ServiceMeshName, defaultDeployConfig.ServiceMesh, "Record decrypted traffic if the cluster is configured with a service mesh and with mtls")
deployCmd.Flags().Bool(configStructs.TlsName, defaultDeployConfig.Tls, "Record tls traffic")
deployCmd.Flags().Bool(configStructs.ProfilerName, defaultDeployConfig.Profiler, "Run pprof server")
deployCmd.Flags().Int(configStructs.MaxLiveStreamsName, defaultDeployConfig.MaxLiveStreams, "Maximum live tcp streams to handle concurrently")
}

View File

@ -54,8 +54,8 @@ func RunKubesharkTap() {
state.targetNamespaces = getNamespaces(kubernetesProvider) state.targetNamespaces = getNamespaces(kubernetesProvider)
conf := getTapConfig() conf := getDeployConfig()
serializedKubesharkConfig, err := getSerializedTapConfig(conf) serializedKubesharkConfig, err := getSerializedDeployConfig(conf)
if err != nil { if err != nil {
log.Error().Err(errormessage.FormatError(err)).Msg("Error serializing Kubeshark config!") log.Error().Err(errormessage.FormatError(err)).Msg("Error serializing Kubeshark config!")
return return
@ -74,12 +74,12 @@ func RunKubesharkTap() {
log.Error().Err(errormessage.FormatError(err)).Msg("Error listing pods!") log.Error().Err(errormessage.FormatError(err)).Msg("Error listing pods!")
} }
if config.Config.Tap.DryRun { if config.Config.Deploy.DryRun {
return return
} }
log.Info().Msg("Waiting for Kubeshark deployment to finish...") log.Info().Msg("Waiting for Kubeshark deployment to finish...")
if state.kubesharkServiceAccountExists, err = resources.CreateTapKubesharkResources(ctx, kubernetesProvider, serializedKubesharkConfig, config.Config.IsNsRestrictedMode(), config.Config.ResourcesNamespace, config.Config.Tap.MaxEntriesDBSizeBytes(), config.Config.Tap.HubResources, config.Config.ImagePullPolicy(), config.Config.LogLevel(), config.Config.Tap.Profiler); err != nil { if state.kubesharkServiceAccountExists, err = resources.CreateTapKubesharkResources(ctx, kubernetesProvider, serializedKubesharkConfig, config.Config.IsNsRestrictedMode(), config.Config.ResourcesNamespace, config.Config.Deploy.MaxEntriesDBSizeBytes(), config.Config.Deploy.HubResources, config.Config.ImagePullPolicy(), config.Config.LogLevel(), config.Config.Deploy.Profiler); err != nil {
var statusError *k8serrors.StatusError var statusError *k8serrors.StatusError
if errors.As(err, &statusError) && (statusError.ErrStatus.Reason == metav1.StatusReasonAlreadyExists) { if errors.As(err, &statusError) && (statusError.ErrStatus.Reason == metav1.StatusReasonAlreadyExists) {
log.Info().Msg("Kubeshark is already running in this namespace, change the `kubeshark-resources-namespace` configuration or run `kubeshark clean` to remove the currently running Kubeshark instance") log.Info().Msg("Kubeshark is already running in this namespace, change the `kubeshark-resources-namespace` configuration or run `kubeshark clean` to remove the currently running Kubeshark instance")
@ -105,12 +105,12 @@ func finishTapExecution(kubernetesProvider *kubernetes.Provider) {
finishKubesharkExecution(kubernetesProvider, config.Config.IsNsRestrictedMode(), config.Config.ResourcesNamespace) finishKubesharkExecution(kubernetesProvider, config.Config.IsNsRestrictedMode(), config.Config.ResourcesNamespace)
} }
func getTapConfig() *models.Config { func getDeployConfig() *models.Config {
conf := models.Config{ conf := models.Config{
MaxDBSizeBytes: config.Config.Tap.MaxEntriesDBSizeBytes(), MaxDBSizeBytes: config.Config.Deploy.MaxEntriesDBSizeBytes(),
InsertionFilter: config.Config.Tap.GetInsertionFilter(), InsertionFilter: config.Config.Deploy.GetInsertionFilter(),
PullPolicy: config.Config.ImagePullPolicyStr, PullPolicy: config.Config.ImagePullPolicyStr,
TapperResources: config.Config.Tap.TapperResources, TapperResources: config.Config.Deploy.TapperResources,
KubesharkResourcesNamespace: config.Config.ResourcesNamespace, KubesharkResourcesNamespace: config.Config.ResourcesNamespace,
AgentDatabasePath: models.DataDirPath, AgentDatabasePath: models.DataDirPath,
ServiceMap: config.Config.ServiceMap, ServiceMap: config.Config.ServiceMap,
@ -126,7 +126,7 @@ The alternative would be to wait for Hub to be ready and then query it for the p
the arguably worse drawback of taking a relatively very long time before the user sees which pods are targeted, if any. the arguably worse drawback of taking a relatively very long time before the user sees which pods are targeted, if any.
*/ */
func printTappedPodsPreview(ctx context.Context, kubernetesProvider *kubernetes.Provider, namespaces []string) error { func printTappedPodsPreview(ctx context.Context, kubernetesProvider *kubernetes.Provider, namespaces []string) error {
if matchingPods, err := kubernetesProvider.ListAllRunningPodsMatchingRegex(ctx, config.Config.Tap.PodRegex(), namespaces); err != nil { if matchingPods, err := kubernetesProvider.ListAllRunningPodsMatchingRegex(ctx, config.Config.Deploy.PodRegex(), namespaces); err != nil {
return err return err
} else { } else {
if len(matchingPods) == 0 { if len(matchingPods) == 0 {
@ -142,18 +142,18 @@ func printTappedPodsPreview(ctx context.Context, kubernetesProvider *kubernetes.
func startTapperSyncer(ctx context.Context, cancel context.CancelFunc, provider *kubernetes.Provider, targetNamespaces []string, startTime time.Time) error { func startTapperSyncer(ctx context.Context, cancel context.CancelFunc, provider *kubernetes.Provider, targetNamespaces []string, startTime time.Time) error {
tapperSyncer, err := kubernetes.CreateAndStartKubesharkTapperSyncer(ctx, provider, kubernetes.TapperSyncerConfig{ tapperSyncer, err := kubernetes.CreateAndStartKubesharkTapperSyncer(ctx, provider, kubernetes.TapperSyncerConfig{
TargetNamespaces: targetNamespaces, TargetNamespaces: targetNamespaces,
PodFilterRegex: *config.Config.Tap.PodRegex(), PodFilterRegex: *config.Config.Deploy.PodRegex(),
KubesharkResourcesNamespace: config.Config.ResourcesNamespace, KubesharkResourcesNamespace: config.Config.ResourcesNamespace,
TapperResources: config.Config.Tap.TapperResources, TapperResources: config.Config.Deploy.TapperResources,
ImagePullPolicy: config.Config.ImagePullPolicy(), ImagePullPolicy: config.Config.ImagePullPolicy(),
LogLevel: config.Config.LogLevel(), LogLevel: config.Config.LogLevel(),
KubesharkApiFilteringOptions: api.TrafficFilteringOptions{ KubesharkApiFilteringOptions: api.TrafficFilteringOptions{
IgnoredUserAgents: config.Config.Tap.IgnoredUserAgents, IgnoredUserAgents: config.Config.Deploy.IgnoredUserAgents,
}, },
KubesharkServiceAccountExists: state.kubesharkServiceAccountExists, KubesharkServiceAccountExists: state.kubesharkServiceAccountExists,
ServiceMesh: config.Config.Tap.ServiceMesh, ServiceMesh: config.Config.Deploy.ServiceMesh,
Tls: config.Config.Tap.Tls, Tls: config.Config.Deploy.Tls,
MaxLiveStreams: config.Config.Tap.MaxLiveStreams, MaxLiveStreams: config.Config.Deploy.MaxLiveStreams,
}, startTime) }, startTime)
if err != nil { if err != nil {
@ -471,10 +471,10 @@ func postFrontStarted(ctx context.Context, kubernetesProvider *kubernetes.Provid
} }
func getNamespaces(kubernetesProvider *kubernetes.Provider) []string { func getNamespaces(kubernetesProvider *kubernetes.Provider) []string {
if config.Config.Tap.AllNamespaces { if config.Config.Deploy.AllNamespaces {
return []string{kubernetes.K8sAllNamespaces} return []string{kubernetes.K8sAllNamespaces}
} else if len(config.Config.Tap.Namespaces) > 0 { } else if len(config.Config.Deploy.Namespaces) > 0 {
return utils.Unique(config.Config.Tap.Namespaces) return utils.Unique(config.Config.Deploy.Namespaces)
} else { } else {
currentNamespace, err := kubernetesProvider.CurrentNamespace() currentNamespace, err := kubernetesProvider.CurrentNamespace()
if err != nil { if err != nil {

View File

@ -6,7 +6,7 @@ import (
var openCmd = &cobra.Command{ var openCmd = &cobra.Command{
Use: "open", Use: "open",
Short: "Open the web UI in the browser", Short: "Open the web UI in the browser.",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
runOpen() runOpen()
return nil return nil

View File

@ -11,9 +11,10 @@ import (
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "kubeshark", Use: "kubeshark",
Short: "A web traffic viewer for kubernetes", Short: "Kubeshark: The Observability and Monitoring Tool For Kubernetes",
Long: `A web traffic viewer for kubernetes Long: `Kubeshark: The Observability and Monitoring Tool For Kubernetes
Further info is available at https://github.com/kubeshark/kubeshark`, An extensible Kubernetes-aware network sniffer and kernel tracer.
For more info: https://kubeshark.co`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error { PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := config.InitConfig(cmd); err != nil { if err := config.InitConfig(cmd); err != nil {
log.Fatal().Err(err).Send() log.Fatal().Err(err).Send()

View File

@ -1,61 +0,0 @@
package cmd
import (
"errors"
"github.com/creasty/defaults"
"github.com/kubeshark/kubeshark/config"
"github.com/kubeshark/kubeshark/config/configStructs"
"github.com/kubeshark/kubeshark/errormessage"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)
var tapCmd = &cobra.Command{
Use: "tap [POD REGEX]",
Short: "Record ingoing traffic of a kubernetes pod",
Long: `Record the ingoing traffic of a kubernetes pod.
Supported protocols are HTTP and gRPC.`,
RunE: func(cmd *cobra.Command, args []string) error {
RunKubesharkTap()
return nil
},
PreRunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 1 {
config.Config.Tap.PodRegexStr = args[0]
} else if len(args) > 1 {
return errors.New("unexpected number of arguments")
}
if err := config.Config.Tap.Validate(); err != nil {
return errormessage.FormatError(err)
}
log.Info().
Str("limit", config.Config.Tap.HumanMaxEntriesDBSize).
Msg("Kubeshark will store the traffic up to a limit. Oldest entries will be removed once the limit is reached.")
return nil
},
}
func init() {
rootCmd.AddCommand(tapCmd)
defaultTapConfig := configStructs.TapConfig{}
if err := defaults.Set(&defaultTapConfig); err != nil {
log.Debug().Err(err).Send()
}
tapCmd.Flags().Uint16P(configStructs.GuiPortTapName, "p", defaultTapConfig.GuiPort, "Provide a custom port for the web interface webserver")
tapCmd.Flags().StringSliceP(configStructs.NamespacesTapName, "n", defaultTapConfig.Namespaces, "Namespaces selector")
tapCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultTapConfig.AllNamespaces, "Tap all namespaces")
tapCmd.Flags().Bool(configStructs.EnableRedactionTapName, defaultTapConfig.EnableRedaction, "Enables redaction of potentially sensitive request/response headers and body values")
tapCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultTapConfig.HumanMaxEntriesDBSize, "Override the default max entries db size")
tapCmd.Flags().String(configStructs.InsertionFilterName, defaultTapConfig.InsertionFilter, "Set the insertion filter. Accepts string or a file path.")
tapCmd.Flags().Bool(configStructs.DryRunTapName, defaultTapConfig.DryRun, "Preview of all pods matching the regex, without tapping them")
tapCmd.Flags().Bool(configStructs.ServiceMeshName, defaultTapConfig.ServiceMesh, "Record decrypted traffic if the cluster is configured with a service mesh and with mtls")
tapCmd.Flags().Bool(configStructs.TlsName, defaultTapConfig.Tls, "Record tls traffic")
tapCmd.Flags().Bool(configStructs.ProfilerName, defaultTapConfig.Profiler, "Run pprof server")
tapCmd.Flags().Int(configStructs.MaxLiveStreamsName, defaultTapConfig.MaxLiveStreams, "Maximum live tcp streams to handle concurrently")
}

View File

@ -57,7 +57,7 @@ func CreateDefaultConfig() ConfigStruct {
type ConfigStruct struct { type ConfigStruct struct {
Hub HubConfig `yaml:"hub"` Hub HubConfig `yaml:"hub"`
Front FrontConfig `yaml:"front"` Front FrontConfig `yaml:"front"`
Tap configStructs.TapConfig `yaml:"tap"` Deploy configStructs.DeployConfig `yaml:"deploy"`
Logs configStructs.LogsConfig `yaml:"logs"` Logs configStructs.LogsConfig `yaml:"logs"`
Config configStructs.ConfigConfig `yaml:"config,omitempty"` Config configStructs.ConfigConfig `yaml:"config,omitempty"`
ImagePullPolicyStr string `yaml:"image-pull-policy" default:"Always"` ImagePullPolicyStr string `yaml:"image-pull-policy" default:"Always"`

View File

@ -26,7 +26,7 @@ const (
MaxLiveStreamsName = "max-live-streams" MaxLiveStreamsName = "max-live-streams"
) )
type TapConfig struct { type DeployConfig struct {
PodRegexStr string `yaml:"regex" default:".*"` PodRegexStr string `yaml:"regex" default:".*"`
GuiPort uint16 `yaml:"gui-port" default:"8899"` GuiPort uint16 `yaml:"gui-port" default:"8899"`
ProxyHost string `yaml:"proxy-host" default:"127.0.0.1"` ProxyHost string `yaml:"proxy-host" default:"127.0.0.1"`
@ -53,17 +53,17 @@ type TapConfig struct {
MaxLiveStreams int `yaml:"max-live-streams" default:"500"` MaxLiveStreams int `yaml:"max-live-streams" default:"500"`
} }
func (config *TapConfig) PodRegex() *regexp.Regexp { func (config *DeployConfig) PodRegex() *regexp.Regexp {
podRegex, _ := regexp.Compile(config.PodRegexStr) podRegex, _ := regexp.Compile(config.PodRegexStr)
return podRegex return podRegex
} }
func (config *TapConfig) MaxEntriesDBSizeBytes() int64 { func (config *DeployConfig) MaxEntriesDBSizeBytes() int64 {
maxEntriesDBSizeBytes, _ := utils.HumanReadableToBytes(config.HumanMaxEntriesDBSize) maxEntriesDBSizeBytes, _ := utils.HumanReadableToBytes(config.HumanMaxEntriesDBSize)
return maxEntriesDBSizeBytes return maxEntriesDBSizeBytes
} }
func (config *TapConfig) GetInsertionFilter() string { func (config *DeployConfig) GetInsertionFilter() string {
insertionFilter := config.InsertionFilter insertionFilter := config.InsertionFilter
if fs.ValidPath(insertionFilter) { if fs.ValidPath(insertionFilter) {
if _, err := os.Stat(insertionFilter); err == nil { if _, err := os.Stat(insertionFilter); err == nil {
@ -87,7 +87,7 @@ func (config *TapConfig) GetInsertionFilter() string {
return insertionFilter return insertionFilter
} }
func getRedactFilter(config *TapConfig) string { func getRedactFilter(config *DeployConfig) string {
if !config.EnableRedaction { if !config.EnableRedaction {
return "" return ""
} }
@ -118,7 +118,7 @@ func getRedactFilter(config *TapConfig) string {
return fmt.Sprintf("redact(\"%s\")", strings.Join(redactValues, "\",\"")) return fmt.Sprintf("redact(\"%s\")", strings.Join(redactValues, "\",\""))
} }
func (config *TapConfig) Validate() error { func (config *DeployConfig) Validate() error {
_, compileErr := regexp.Compile(config.PodRegexStr) _, compileErr := regexp.Compile(config.PodRegexStr)
if compileErr != nil { if compileErr != nil {
return fmt.Errorf("%s is not a valid regex %s", config.PodRegexStr, compileErr) return fmt.Errorf("%s is not a valid regex %s", config.PodRegexStr, compileErr)