Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed committed Dec 30, 2024
1 parent a1a321c commit 360e011
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 39 deletions.
57 changes: 55 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ func Execute() {

// Doit runs the scans and lints pass over the specified cluster.
func doIt(cmd *cobra.Command, args []string) {
bomb(initLogs())

defer func() {
if err := recover(); err != nil {
pkg.BailOut(err.(error))
}
}()

zerolog.SetGlobalLevel(zerolog.DebugLevel)
clearScreen()
bomb(flags.Validate())
flags.StandAlone = true
Expand All @@ -84,7 +85,7 @@ func bomb(err error) {
if err == nil {
return
}
panic(fmt.Errorf("💥 %s\n", report.Colorize(err.Error(), report.ColorRed)))
panic(fmt.Errorf("💥 %s", report.Colorize(err.Error(), report.ColorRed)))
}

func initPopeyeFlags() {
Expand Down Expand Up @@ -166,6 +167,15 @@ func initPopeyeFlags() {
[]string{},
"Specify which resources to include in the scan ie -s po,svc",
)

rootCmd.Flags().IntVarP(flags.LogLevel, "log-level", "v",
1,
"Specify log level. Use 0|1|2|3|4 for disable|info|warn|error|debug",
)
rootCmd.Flags().StringVarP(flags.LogFile, "logs", "",
pkg.LogFile,
"Specify log file location. Use `none` for stdout",
)
}

func initKubeConfigFlags() {
Expand Down Expand Up @@ -212,6 +222,49 @@ func initKubeConfigFlags() {
)
}

func initLogs() error {
var logs string
if *flags.LogFile != "none" {
logs = *flags.LogFile
}

var file = os.Stdout
if logs != "" {
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
var err error
file, err = os.OpenFile(logs, mod, 0644)
if err != nil {
return fmt.Errorf("unable to create Popeye log file: %w", err)
}
}
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})

if flags.LogLevel == nil {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
} else {
zerolog.SetGlobalLevel(toLogLevel(*flags.LogLevel))
}

return nil
}

func toLogLevel(level int) zerolog.Level {
switch level {
case -1:
return zerolog.TraceLevel
case 0:
return zerolog.Disabled
case 1:
return zerolog.InfoLevel
case 2:
return zerolog.WarnLevel
case 3:
return zerolog.ErrorLevel
default:
return zerolog.DebugLevel
}
}

func initFlags() {
initPopeyeFlags()
initKubeConfigFlags()
Expand Down
3 changes: 3 additions & 0 deletions internal/issues/assets/codes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ codes:
307:
message: "%s references a non existing ServiceAccount: %q"
severity: 2
308:
message: Uses "default" bound ServiceAccount. Could be a security risk
severity: 3

# General
400:
Expand Down
2 changes: 1 addition & 1 deletion internal/issues/codes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestCodesLoad(t *testing.T) {
cc, err := issues.LoadCodes()

assert.Nil(t, err)
assert.Equal(t, 116, len(cc.Glossary))
assert.Equal(t, 117, len(cc.Glossary))
assert.Equal(t, "No liveness probe", cc.Glossary[103].Message)
assert.Equal(t, rules.WarnLevel, cc.Glossary[103].Severity)
}
Expand Down
16 changes: 0 additions & 16 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,10 @@
package main

import (
"fmt"
"os"

"github.com/derailed/popeye/cmd"
"github.com/derailed/popeye/pkg"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
_ "k8s.io/client-go/plugin/pkg/client/auth"
)

func init() {
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
if file, err := os.OpenFile(pkg.LogFile, mod, 0644); err == nil {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
} else {
fmt.Printf("Unable to create Popeye log file %v. Exiting...", err)
os.Exit(1)
}
}

func main() {
cmd.Execute()
}
8 changes: 6 additions & 2 deletions pkg/config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ type Flags struct {
ActiveNamespace *string
ForceExitZero *bool
MinScore *int
LogLevel *int
LogFile *string
}

// NewFlags returns new configuration flags.
Expand All @@ -62,15 +64,17 @@ func NewFlags() *Flags {
PushGateway: newPushGateway(),
ForceExitZero: boolPtr(false),
MinScore: intPtr(0),
LogLevel: intPtr(0),
LogFile: strPtr(""),
}
}

func (f *Flags) Validate() error {
if !IsBoolSet(f.Save) && IsStrSet(f.OutputFile) {
return errors.New("'--save' must be used in conjunction with 'output-file'.")
return errors.New("'--save' must be used in conjunction with 'output-file'")
}
if IsBoolSet(f.Save) && IsStrSet(f.S3.Bucket) {
return errors.New("'--save' cannot be used in conjunction with 's3-bucket'.")
return errors.New("'--save' cannot be used in conjunction with 's3-bucket'")
}

if !in(outputs, f.Output) {
Expand Down
26 changes: 8 additions & 18 deletions pkg/popeye.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@ func (p *Popeye) buildCtx(ctx context.Context) context.Context {
}
ns, err := p.client().Config().CurrentNamespaceName()
if err != nil {
log.Warn().Msgf("Unable to determine current namespace: %v. Using `default` namespace", err)
ns = client.DefaultNamespace
}
ctx = context.WithValue(ctx, internal.KeyNamespace, ns)

return ctx
return context.WithValue(ctx, internal.KeyNamespace, ns)
}

func (p *Popeye) validateSpinach(ss scrub.Scrubs) error {
Expand All @@ -226,10 +226,6 @@ func (p *Popeye) lint() (int, int, error) {
log.Debug().Msgf("Lint %v", time.Since(t))
}(time.Now())

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ctx = p.buildCtx(ctx)

codes, err := issues.LoadCodes()
if err != nil {
return 0, 0, err
Expand All @@ -250,22 +246,18 @@ func (p *Popeye) lint() (int, int, error) {
if err := p.validateSpinach(scrubers); err != nil {
return 0, 0, err
}

ctx := p.buildCtx(context.Background())
sections, ans := p.config.Sections(), p.client().ActiveNamespace()
for k, fn := range scrubers {
gvr, ok := internal.Glossary[k]
if !ok || gvr == types.BlankGVR {
continue
}

if p.aliases.Exclude(gvr, p.config.Sections()) {
if client.IsNamespaced(ans) && p.aliases.IsNamespaced(gvr) || p.aliases.Exclude(gvr, sections) {
continue
}
// Skip node linter if active namespace is set.
if gvr == internal.Glossary[internal.NO] && p.client().ActiveNamespace() != client.AllNamespaces {
continue
}

runners[gvr] = fn(ctx, cache, codes)

}

total, errCount := len(runners), 0
Expand Down Expand Up @@ -304,12 +296,10 @@ func (p *Popeye) runLinter(ctx context.Context, gvr types.GVR, l scrub.Linter, c
}
}()

callCtx := ctx
if !p.aliases.IsNamespaced(gvr) {
callCtx = context.WithValue(ctx, internal.KeyNamespace, client.ClusterScope)
ctx = context.WithValue(ctx, internal.KeyNamespace, client.ClusterScope)
}

if err := l.Lint(callCtx); err != nil {
if err := l.Lint(ctx); err != nil {
p.builder.AddError(err)
}
o := l.Outcome().Filter(rules.Level(p.config.LintLevel))
Expand Down

0 comments on commit 360e011

Please sign in to comment.