Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support in cluster context #175

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 63 additions & 39 deletions pkg/cmd/sniff.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,16 @@ const tcpdumpRemotePath = "/tmp/static-tcpdump"
var tcpdumpLocalBinaryPathLookupList []string

type Ksniff struct {
configFlags *genericclioptions.ConfigFlags
resultingContext *api.Context
clientset *kubernetes.Clientset
restConfig *rest.Config
rawConfig api.Config
settings *config.KsniffSettings
snifferService sniffer.SnifferService
wireshark *exec.Cmd
clientset *kubernetes.Clientset
restConfig *rest.Config
settings *config.KsniffSettings
snifferService sniffer.SnifferService
wireshark *exec.Cmd
namespace string
}

func NewKsniff(settings *config.KsniffSettings) *Ksniff {
return &Ksniff{settings: settings, configFlags: genericclioptions.NewConfigFlags(true)}
return &Ksniff{settings: settings}
}

func NewCmdSniff(streams genericclioptions.IOStreams) *cobra.Command {
Expand Down Expand Up @@ -200,47 +198,77 @@ func (o *Ksniff) Complete(cmd *cobra.Command, args []string) error {
return err
}

o.rawConfig, err = o.configFlags.ToRawKubeConfigLoader().RawConfig()
useInClusterConfig := o.settings.UserSpecifiedKubeContext == "" &&
len(os.Getenv("KUBERNETES_SERVICE_HOST")) != 0 &&
len(os.Getenv("KUBERNETES_SERVICE_PORT")) != 0

if useInClusterConfig {
o.restConfig, err = rest.InClusterConfig()
if err != nil {
return fmt.Errorf("error getting in cluster config: %s", err)
}
if o.settings.UserSpecifiedNamespace != "" {
o.namespace = o.settings.UserSpecifiedNamespace
} else {
o.namespace = "default"
}
} else {
o.restConfig, err = o.userKubeConfig()
if err != nil {
return err
}
}

o.restConfig.Timeout = 30 * time.Second

o.clientset, err = kubernetes.NewForConfig(o.restConfig)
if err != nil {
return err
}

return nil
}

func (o *Ksniff) userKubeConfig() (*rest.Config, error) {
var restConfig *rest.Config

configFlags := genericclioptions.NewConfigFlags(true)
rawConfig, err := configFlags.ToRawKubeConfigLoader().RawConfig()
if err != nil {
return restConfig, err
}

var currentContext *api.Context
var exists bool

if o.settings.UserSpecifiedKubeContext != "" {
currentContext, exists = o.rawConfig.Contexts[o.settings.UserSpecifiedKubeContext]
currentContext, exists = rawConfig.Contexts[o.settings.UserSpecifiedKubeContext]
if !exists {
return restConfig, fmt.Errorf("context '%s' not found", o.settings.UserSpecifiedKubeContext)
}
} else {
currentContext, exists = o.rawConfig.Contexts[o.rawConfig.CurrentContext]
}
currentContext, exists = rawConfig.Contexts[rawConfig.CurrentContext]
if !exists {
return restConfig, errors.New("current context not found")
}

if !exists {
return errors.New("context doesn't exist")
}

loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
configOverrides := &clientcmd.ConfigOverrides{
CurrentContext: o.settings.UserSpecifiedKubeContext,
}
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
o.restConfig, err = kubeConfig.ClientConfig()
if err != nil {
return err
}

o.restConfig.Timeout = 30 * time.Second

o.clientset, err = kubernetes.NewForConfig(o.restConfig)
if err != nil {
return err
}

o.resultingContext = currentContext.DeepCopy()
resultingContext := currentContext.DeepCopy()
if o.settings.UserSpecifiedNamespace != "" {
o.resultingContext.Namespace = o.settings.UserSpecifiedNamespace
resultingContext.Namespace = o.settings.UserSpecifiedNamespace
}

return nil
o.namespace = resultingContext.Namespace

restConfig, err = kubeConfig.ClientConfig()
return restConfig, err
}

func (o *Ksniff) buildTcpdumpBinaryPathLookupList() ([]string, error) {
Expand All @@ -264,11 +292,7 @@ func (o *Ksniff) buildTcpdumpBinaryPathLookupList() ([]string, error) {
}

func (o *Ksniff) Validate() error {
if len(o.rawConfig.CurrentContext) == 0 {
return errors.New("context doesn't exist")
}

if o.resultingContext.Namespace == "" {
if o.namespace == "" {
return errors.New("namespace value is empty should be custom or default")
}

Expand All @@ -282,13 +306,13 @@ func (o *Ksniff) Validate() error {

log.Infof("using tcpdump path at: '%s'", o.settings.UserSpecifiedLocalTcpdumpPath)
} else if o.settings.UserSpecifiedServiceAccount != "" {
_, err := o.clientset.CoreV1().ServiceAccounts(o.resultingContext.Namespace).Get(context.TODO(), o.settings.UserSpecifiedServiceAccount, v1.GetOptions{})
_, err := o.clientset.CoreV1().ServiceAccounts(o.namespace).Get(context.TODO(), o.settings.UserSpecifiedServiceAccount, v1.GetOptions{})
if err != nil {
return err
}
}

pod, err := o.clientset.CoreV1().Pods(o.resultingContext.Namespace).Get(context.TODO(), o.settings.UserSpecifiedPodName, v1.GetOptions{})
pod, err := o.clientset.CoreV1().Pods(o.namespace).Get(context.TODO(), o.settings.UserSpecifiedPodName, v1.GetOptions{})
if err != nil {
return err
}
Expand All @@ -315,7 +339,7 @@ func (o *Ksniff) Validate() error {
return err
}

kubernetesApiService := kube.NewKubernetesApiService(o.clientset, o.restConfig, o.resultingContext.Namespace)
kubernetesApiService := kube.NewKubernetesApiService(o.clientset, o.restConfig, o.namespace)

if o.settings.UserSpecifiedPrivilegedMode {
log.Info("sniffing method: privileged pod")
Expand Down Expand Up @@ -403,7 +427,7 @@ func (o *Ksniff) setupSignalHandler() chan interface{} {

func (o *Ksniff) Run() error {
log.Infof("sniffing on pod: '%s' [namespace: '%s', container: '%s', filter: '%s', interface: '%s']",
o.settings.UserSpecifiedPodName, o.resultingContext.Namespace, o.settings.UserSpecifiedContainer, o.settings.UserSpecifiedFilter, o.settings.UserSpecifiedInterface)
o.settings.UserSpecifiedPodName, o.namespace, o.settings.UserSpecifiedContainer, o.settings.UserSpecifiedFilter, o.settings.UserSpecifiedInterface)

err := o.snifferService.Setup()
if err != nil {
Expand Down Expand Up @@ -441,7 +465,7 @@ func (o *Ksniff) Run() error {
} else {
log.Info("spawning wireshark!")

title := fmt.Sprintf("gui.window_title:%s/%s/%s", o.resultingContext.Namespace, o.settings.UserSpecifiedPodName, o.settings.UserSpecifiedContainer)
title := fmt.Sprintf("gui.window_title:%s/%s/%s", o.namespace, o.settings.UserSpecifiedPodName, o.settings.UserSpecifiedContainer)
o.wireshark = exec.Command("wireshark", "-k", "-i", "-", "-o", title)

stdinWriter, err := o.wireshark.StdinPipe()
Expand Down