diff --git a/.gitignore b/.gitignore index 60389ddc6..6990187a7 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,8 @@ cypress.env.json # Object files *.o +# Binaries bin + +# Scripts +scripts/ diff --git a/cmd/tapRunner.go b/cmd/tapRunner.go index dd42b2bc8..970b3d286 100644 --- a/cmd/tapRunner.go +++ b/cmd/tapRunner.go @@ -409,6 +409,7 @@ func postHubStarted(ctx context.Context, kubernetesProvider *kubernetes.Provider "/echo", ) + // Create workers err := kubernetes.CreateWorkers( kubernetesProvider, state.selfServiceAccountExists, @@ -425,12 +426,28 @@ func postHubStarted(ctx context.Context, kubernetesProvider *kubernetes.Provider log.Error().Err(err).Send() } + // Pod regex connector.PostRegexToHub(config.Config.Tap.PodRegexStr, state.targetNamespaces) + // License if config.Config.License != "" { connector.PostLicense(config.Config.License) } + // Scripting + connector.PostConsts(config.Config.Scripting.Consts) + + var scripts []*configStructs.Script + scripts, err = config.Config.Scripting.GetScripts() + if err != nil { + log.Error().Err(err).Send() + } + + for _, script := range scripts { + connector.PostScript(script) + } + + // Hub proxy URL url := kubernetes.GetLocalhostOnPort(config.Config.Tap.Proxy.Hub.SrcPort) log.Info().Str("url", url).Msg(fmt.Sprintf(utils.Green, "Hub is available at:")) } diff --git a/config/configStruct.go b/config/configStruct.go index ad0face60..d36967cda 100644 --- a/config/configStruct.go +++ b/config/configStruct.go @@ -27,15 +27,16 @@ type KubeConfig struct { } type ConfigStruct struct { - Tap configStructs.TapConfig `yaml:"tap"` - Logs configStructs.LogsConfig `yaml:"logs"` - Config configStructs.ConfigConfig `yaml:"config,omitempty"` - Kube KubeConfig `yaml:"kube"` - SelfNamespace string `yaml:"selfnamespace" default:"kubeshark"` - DumpLogs bool `yaml:"dumplogs" default:"false"` - ConfigFilePath string `yaml:"configpath,omitempty" readonly:""` - HeadlessMode bool `yaml:"headless" default:"false"` - License string `yaml:"license" default:""` + Tap configStructs.TapConfig `yaml:"tap"` + Logs configStructs.LogsConfig `yaml:"logs"` + Config configStructs.ConfigConfig `yaml:"config,omitempty"` + Kube KubeConfig `yaml:"kube"` + SelfNamespace string `yaml:"selfnamespace" default:"kubeshark"` + DumpLogs bool `yaml:"dumplogs" default:"false"` + ConfigFilePath string `yaml:"configpath,omitempty" readonly:""` + HeadlessMode bool `yaml:"headless" default:"false"` + License string `yaml:"license" default:""` + Scripting configStructs.ScriptingConfig `yaml:"scripting"` } func (config *ConfigStruct) SetDefaults() { diff --git a/config/configStructs/scriptingConfig.go b/config/configStructs/scriptingConfig.go new file mode 100644 index 000000000..530b7ed29 --- /dev/null +++ b/config/configStructs/scriptingConfig.go @@ -0,0 +1,74 @@ +package configStructs + +import ( + "io/fs" + "io/ioutil" + "os" + "path/filepath" + + "github.com/robertkrimen/otto/ast" + "github.com/robertkrimen/otto/file" + "github.com/robertkrimen/otto/parser" +) + +type ScriptingConfig struct { + Consts map[string]string `yaml:"consts"` + Source string `yaml:"source" default:""` +} + +type Script struct { + Title string `json:"title"` + Code string `json:"code"` +} + +func (config *ScriptingConfig) GetScripts() (scripts []*Script, err error) { + if config.Source == "" { + return + } + + var files []fs.FileInfo + files, err = ioutil.ReadDir(config.Source) + if err != nil { + return + } + + for _, f := range files { + if f.IsDir() { + continue + } + + filename := f.Name() + var body []byte + body, err = os.ReadFile(filepath.Join(config.Source, filename)) + if err != nil { + return + } + content := string(body) + + var program *ast.Program + program, err = parser.ParseFile(nil, filename, content, parser.StoreComments) + if err != nil { + return + } + + var title string + code := content + + var idx0 file.Idx + for node, comments := range program.Comments { + if (idx0 > 0 && node.Idx0() > idx0) || len(comments) == 0 { + continue + } + idx0 = node.Idx0() + + title = comments[0].Text + } + + scripts = append(scripts, &Script{ + Title: title, + Code: code, + }) + } + + return +} diff --git a/go.mod b/go.mod index fe82bb749..d9fb7df35 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/docker/go-units v0.4.0 github.com/google/go-github/v37 v37.0.0 github.com/kubeshark/base v0.5.1 + github.com/robertkrimen/otto v0.2.1 github.com/rs/zerolog v1.28.0 github.com/spf13/cobra v1.3.0 github.com/spf13/pflag v1.0.5 @@ -92,6 +93,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/cli-runtime v0.23.3 // indirect k8s.io/component-base v0.23.3 // indirect diff --git a/go.sum b/go.sum index 23273adf7..8e1ebe1dd 100644 --- a/go.sum +++ b/go.sum @@ -543,6 +543,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGGF0= +github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1135,6 +1137,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= diff --git a/internal/connect/hub.go b/internal/connect/hub.go index da847de7e..66bf97401 100644 --- a/internal/connect/hub.go +++ b/internal/connect/hub.go @@ -9,6 +9,7 @@ import ( "time" "github.com/kubeshark/kubeshark/config" + "github.com/kubeshark/kubeshark/config/configStructs" "github.com/kubeshark/kubeshark/utils" "github.com/rs/zerolog/log" @@ -175,3 +176,51 @@ func (connector *Connector) PostLicense(license string) { } } } + +func (connector *Connector) PostConsts(consts map[string]string) { + if len(consts) == 0 { + return + } + + postConstsUrl := fmt.Sprintf("%s/scripts/consts", connector.url) + + if payloadMarshalled, err := json.Marshal(consts); err != nil { + log.Error().Err(err).Msg("Failed to marshal the payload:") + } else { + ok := false + for !ok { + if _, err = utils.Post(postConstsUrl, "application/json", bytes.NewBuffer(payloadMarshalled), connector.client); err != nil { + if _, ok := err.(*url.Error); ok { + break + } + log.Debug().Err(err).Msg("Failed sending the constants to Hub:") + } else { + ok = true + log.Debug().Interface("consts", consts).Msg("Reported constants to Hub:") + } + time.Sleep(time.Second) + } + } +} + +func (connector *Connector) PostScript(script *configStructs.Script) { + postScriptUrl := fmt.Sprintf("%s/scripts", connector.url) + + if payloadMarshalled, err := json.Marshal(script); err != nil { + log.Error().Err(err).Msg("Failed to marshal the payload:") + } else { + ok := false + for !ok { + if _, err = utils.Post(postScriptUrl, "application/json", bytes.NewBuffer(payloadMarshalled), connector.client); err != nil { + if _, ok := err.(*url.Error); ok { + break + } + log.Debug().Err(err).Msg("Failed sending the script to Hub:") + } else { + ok = true + log.Debug().Interface("script", script).Msg("Reported script to Hub:") + } + time.Sleep(time.Second) + } + } +}