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

cmd(profile): improve karmor profile for unorchestrated mode #465

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
5 changes: 4 additions & 1 deletion cmd/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
package cmd

import (
"github.com/kubearmor/kubearmor-client/profile"
profileclient "github.com/kubearmor/kubearmor-client/profile/Client"
"github.com/spf13/cobra"
)

var profileOptions profileclient.Options
var profileOptions profile.Options

// profileCmd represents the profile command
var profilecmd = &cobra.Command{
Expand All @@ -25,6 +26,8 @@ func init() {
rootCmd.AddCommand(profilecmd)
profilecmd.Flags().StringVar(&profileOptions.GRPC, "gRPC", "", "use gRPC")
profilecmd.Flags().StringVarP(&profileOptions.Namespace, "namespace", "n", "", "Filter using namespace")
profilecmd.Flags().StringVar(&profileOptions.LogFilter, "logFilter", "system", "Filter for what kinds of alerts and logs to receive, {policy|system|all}")
profilecmd.Flags().StringVar(&profileOptions.LogType, "logType", "ContainerLog", "Log type you want (Eg:ContainerLog/HostLog)")
profilecmd.Flags().StringVar(&profileOptions.Pod, "pod", "", "Filter using Pod name")
profilecmd.Flags().StringVarP(&profileOptions.Container, "container", "c", "", "name of the container ")
profilecmd.Flags().BoolVar(&profileOptions.Save, "save", false, "Save Profile data in json format")
Expand Down
6 changes: 4 additions & 2 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,11 @@ func StartObserver(c *k8s.Client, o Options) error {
} else {
pf, err := utils.InitiatePortForward(c, port, port, matchLabels, targetSvc)
if err != nil {
return err
fmt.Fprintf(os.Stderr, "Failed to initiate port forward (%s)\n", err)
gRPC = "localhost:32767"
} else {
gRPC = "localhost:" + strconv.FormatInt(pf.LocalPort, 10)
}
gRPC = "localhost:" + strconv.FormatInt(pf.LocalPort, 10)
}

if o.MsgPath == "none" && o.LogPath == "none" {
Expand Down
86 changes: 36 additions & 50 deletions profile/Client/profileClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"github.com/evertras/bubble-table/table"
pb "github.com/kubearmor/KubeArmor/protobuf"
klog "github.com/kubearmor/kubearmor-client/log"
profile "github.com/kubearmor/kubearmor-client/profile"
"github.com/kubearmor/kubearmor-client/profile"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -62,15 +62,6 @@ var (
}
)

// Options for filter
type Options struct {
Namespace string
Pod string
GRPC string
Container string
Save bool
}

// Model for main Bubble Tea
type Model struct {
File table.Model
Expand All @@ -85,7 +76,8 @@ type Model struct {
height int
width int

state sessionState
state sessionState
profileOptions profile.Options
}

// SomeData stores incoming row data
Expand All @@ -100,35 +92,37 @@ func waitForActivity() tea.Cmd {
}
}

var o1 Options
var o1 profile.Options

func generateColumns(Operation string) []table.Column {
CountCol := table.NewFlexColumn(ColumnCount, "Count", 1).WithStyle(ColumnStyle).WithFiltered(true)
func generateColumns(o profile.Options, Operation string) []table.Column {
var columns []table.Column

CountCol := table.NewFlexColumn(ColumnCount, "Count", 1).WithStyle(ColumnStyle).WithFiltered(true)
Namespace := table.NewFlexColumn(ColumnNamespace, "Namespace", 2).WithStyle(ColumnStyle).WithFiltered(true)

ContainerName := table.NewFlexColumn(ColumnContainerName, "ContainerName", 4).WithStyle(ColumnStyle).WithFiltered(true)

ProcName := table.NewFlexColumn(ColumnProcessName, "ProcessName", 3).WithStyle(ColumnStyle).WithFiltered(true)

Resource := table.NewFlexColumn(ColumnResource, Operation, 6).WithStyle(
lipgloss.NewStyle().
Foreground(lipgloss.Color("202")).
Align(lipgloss.Center)).WithFiltered(true)

Result := table.NewFlexColumn(ColumnResult, "Result", 1).WithStyle(ColumnStyle).WithFiltered(true)

Timestamp := table.NewFlexColumn(ColumnTimestamp, "TimeStamp", 3).WithStyle(ColumnStyle)

return []table.Column{
Namespace,
ContainerName,
if o.LogType == "ContainerLog" {
columns = append(columns, []table.Column{
Namespace,
ContainerName,
}...)
}
columns = append(columns, []table.Column{
ProcName,
Resource,
Result,
CountCol,
Timestamp,
}
}...)

return columns
}

// Init calls initial functions if needed
Expand All @@ -139,21 +133,21 @@ func (m Model) Init() tea.Cmd {
}

// NewModel initializates new bubbletea model
func NewModel() Model {
func NewModel(o profile.Options) Model {
model := Model{
File: table.New(generateColumns("File")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
Process: table.New(generateColumns("Process")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
Network: table.New(generateColumns("Network")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
Syscall: table.New(generateColumns("Syscall")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
File: table.New(generateColumns(o, "File")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
Process: table.New(generateColumns(o, "Process")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
Network: table.New(generateColumns(o, "Network")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
Syscall: table.New(generateColumns(o, "Syscall")).WithBaseStyle(styleBase).WithPageSize(30).Filtered(true),
tabs: &tabs{
active: "Lip Gloss",
items: []string{"Process", "File", "Network", "Syscall"},
},
keys: keys,
help: help.New(),
state: processview,
keys: keys,
help: help.New(),
state: processview,
profileOptions: o,
}

return model
}

Expand All @@ -179,9 +173,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Quit

}

switch msg.String() {

case "tab":
switch m.state {
case processview:
Expand All @@ -193,21 +185,17 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case syscallview:
m.state = processview
}

case "u":
m.File = m.File.WithPageSize(m.File.PageSize() - 1)
m.Network = m.Network.WithPageSize(m.Network.PageSize() - 1)
m.Process = m.Process.WithPageSize(m.Process.PageSize() - 1)
m.Syscall = m.Syscall.WithPageSize(m.Syscall.PageSize() - 1)

case "i":
m.File = m.File.WithPageSize(m.File.PageSize() + 1)
m.Network = m.Network.WithPageSize(m.Network.PageSize() + 1)
m.Process = m.Process.WithPageSize(m.Process.PageSize() + 1)
m.Syscall = m.Syscall.WithPageSize(m.Syscall.PageSize() + 1)

}

switch m.state {
case processview:
m.Process = m.Process.Focused(true)
Expand All @@ -217,33 +205,29 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.File = m.File.Focused(true)
m.File, cmd = m.File.Update(msg)
cmds = append(cmds, cmd)

case networkview:
m.Network = m.Network.Focused(true)
m.Network, cmd = m.Network.Update(msg)
cmds = append(cmds, cmd)

case syscallview:
m.Syscall = m.Syscall.Focused(true)
m.Syscall, cmd = m.Syscall.Update(msg)
cmds = append(cmds, cmd)
}
case klog.EventInfo:
profile.TelMutex.RLock()
m.File = m.File.WithRows(generateRowsFromData(profile.Telemetry, "File")).WithColumns(generateColumns("File"))
m.File = m.File.WithRows(generateRowsFromData(profile.Telemetry, "File")).WithColumns(generateColumns(m.profileOptions, "File"))
m.File = m.File.SortByAsc(ColumnNamespace).ThenSortByAsc(ColumnContainerName).ThenSortByAsc(ColumnProcessName).ThenSortByAsc(ColumnCount).ThenSortByAsc(ColumnResource)
m.Process = m.Process.WithRows(generateRowsFromData(profile.Telemetry, "Process")).WithColumns(generateColumns("Process"))
m.Process = m.Process.WithRows(generateRowsFromData(profile.Telemetry, "Process")).WithColumns(generateColumns(m.profileOptions, "Process"))
m.Process = m.Process.SortByAsc(ColumnNamespace).ThenSortByAsc(ColumnContainerName).ThenSortByAsc(ColumnProcessName).ThenSortByAsc(ColumnCount).ThenSortByAsc(ColumnResource)
m.Network = m.Network.WithRows(generateRowsFromData(profile.Telemetry, "Network")).WithColumns(generateColumns("Network"))
m.Network = m.Network.WithRows(generateRowsFromData(profile.Telemetry, "Network")).WithColumns(generateColumns(m.profileOptions, "Network"))
m.Network = m.Network.SortByAsc(ColumnNamespace).ThenSortByAsc(ColumnContainerName).ThenSortByAsc(ColumnProcessName).ThenSortByAsc(ColumnCount).ThenSortByAsc(ColumnResource)
m.Syscall = m.Syscall.WithRows(generateRowsFromData(profile.Telemetry, "Syscall")).WithColumns(generateColumns("Syscall"))
m.Syscall = m.Syscall.WithRows(generateRowsFromData(profile.Telemetry, "Syscall")).WithColumns(generateColumns(m.profileOptions, "Syscall"))
m.Syscall = m.Syscall.SortByAsc(ColumnNamespace).ThenSortByAsc(ColumnContainerName).ThenSortByAsc(ColumnProcessName).ThenSortByAsc(ColumnCount).ThenSortByAsc(ColumnResource)
profile.TelMutex.RUnlock()

return m, waitForActivity()

}

return m, tea.Batch(cmds...)
}

Expand Down Expand Up @@ -481,17 +465,19 @@ func generateRowsFromData(data []pb.Log, Operation string) []table.Row {
}

// Start entire TUI
func Start(o Options) {
o1 = Options{
func Start(o profile.Options) {
o1 = profile.Options{
Namespace: o.Namespace,
Pod: o.Pod,
GRPC: o.GRPC,
LogFilter: o.LogFilter,
LogType: o.LogType,
Container: o.Container,
Save: o.Save,
}
p := tea.NewProgram(NewModel(), tea.WithAltScreen())
p := tea.NewProgram(NewModel(o1), tea.WithAltScreen())
go func() {
err := profile.GetLogs(o1.GRPC)
err := profile.GetLogs(o1)
if err != nil {
p.Quit()
profile.ErrChan <- err
Expand Down
22 changes: 17 additions & 5 deletions profile/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,20 @@ var Telemetry []pb.Log
// TelMutex to prevent deadlock
var TelMutex sync.RWMutex

// Options for filter
type Options struct {
Namespace string
Pod string
LogFilter string
LogType string
GRPC string
Container string
Save bool
}

// GetLogs to fetch logs
func GetLogs(grpc string) error {
errCh := KarmorProfileStart("system", grpc)
func GetLogs(o Options) error {
errCh := KarmorProfileStart(o)
var err error
if eventChan == nil {
log.Error("event channel not set. Did you call KarmorQueueLog()?")
Expand Down Expand Up @@ -58,7 +69,7 @@ func GetLogs(grpc string) error {
}

// KarmorProfileStart starts observer
func KarmorProfileStart(logFilter string, grpc string) <-chan error {
func KarmorProfileStart(o Options) <-chan error {
ErrChan = make(chan error, 1)
if eventChan == nil {
eventChan = make(chan klog.EventInfo)
Expand All @@ -71,10 +82,11 @@ func KarmorProfileStart(logFilter string, grpc string) <-chan error {
go func() {
//defer close(ErrChan)
err = klog.StartObserver(client, klog.Options{
LogFilter: logFilter,
LogFilter: o.LogFilter,
LogType: o.LogType,
MsgPath: "none",
EventChan: eventChan,
GRPC: grpc,
GRPC: o.GRPC,
})

select {
Expand Down