Skip to content

Commit

Permalink
Merge pull request #282 from derailed/popeye/release_v0.20.2
Browse files Browse the repository at this point in the history
Release v0.20.2
  • Loading branch information
derailed authored Feb 19, 2024
2 parents 136c03e + 2d1552c commit dd8eafd
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 74 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NAME := popeye
PACKAGE := github.com/derailed/$(NAME)
VERSION := v0.20.1
VERSION := v0.20.2
GIT := $(shell git rev-parse --short HEAD)
DATE := $(shell date +%FT%T%Z)
IMG_NAME := derailed/popeye
Expand Down
25 changes: 25 additions & 0 deletions change_logs/release_v0.20.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<img src="https://raw.githubusercontent.com/derailed/popeye/master/assets/popeye_logo.png" align="right" width="200" height="auto"/>

# Release v0.20.2

## Notes

Thank you to all that contributed with flushing out issues and enhancements for Popeye! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make Popeye better is as ever very much noticed and appreciated!

This project offers a GitHub Sponsor button (over here 👆). As you well know this is not pimped out by big corps with deep pockets. If you feel `Popeye` is saving you cycles diagnosing potential cluster issues please consider sponsoring this project!! It does go a long way in keeping our servers lights on and beers in our fridge.

Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)

---

## Maintenance Release

---

## Resolved Issues

. [#280](https://github.com/derailed/popeye/issues/280) No RunInfo in context

---

<img src="https://raw.githubusercontent.com/derailed/popeye/master/assets/imhotep_logo.png" width="32" height="auto"/>&nbsp; © 2024 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
31 changes: 1 addition & 30 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"os"
"path/filepath"
"runtime/debug"
"strings"

"github.com/derailed/popeye/internal/report"
Expand Down Expand Up @@ -55,11 +54,7 @@ func Execute() {
func doIt(cmd *cobra.Command, args []string) {
defer func() {
if err := recover(); err != nil {
printMsgLogo("DOH", "X", report.ColorOrangish, report.ColorRed)
fmt.Printf("\n\nBoom! %v\n", err)
log.Error().Msgf("%v", err)
log.Error().Msg(string(debug.Stack()))
os.Exit(1)
pkg.BailOut(err.(error))
}
}()

Expand Down Expand Up @@ -300,27 +295,3 @@ func clearScreen() {
}
fmt.Print("\033[H\033[2J")
}

func printMsgLogo(msg, eye string, title, logo report.Color) {
for i, s := range report.GraderLogo {
switch i {
case 0, 1, 2:
s = strings.Replace(s, "o", string(msg[i]), 1)
case 3:
s = strings.Replace(s, "a", eye, 1)
}

if i < len(report.Popeye) {
fmt.Printf("%s", report.Colorize(report.Popeye[i], title))
fmt.Printf("%s", strings.Repeat(" ", 22))
} else {
if i == 4 {
fmt.Printf("%s", report.Colorize(" Biffs`em and Buffs`em!", logo))
fmt.Printf("%s", strings.Repeat(" ", 26))
} else {
fmt.Printf("%s", strings.Repeat(" ", 50))
}
}
fmt.Println(report.Colorize(s, logo))
}
}
14 changes: 11 additions & 3 deletions internal/cache/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

package cache

import "github.com/Masterminds/semver"
import (
"errors"

"github.com/Masterminds/semver"
)

// ClusterKey tracks Cluster resource references
const ClusterKey = "cl"
Expand All @@ -19,6 +23,10 @@ func NewCluster(v *semver.Version) *Cluster {
}

// ListVersion returns cluster server version.
func (c *Cluster) ListVersion() *semver.Version {
return c.rev
func (c *Cluster) ListVersion() (*semver.Version, error) {
if c.rev == nil {
return nil, errors.New("unable to assert cluster version")
}

return c.rev, nil
}
5 changes: 3 additions & 2 deletions internal/cache/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ func init() {
func TestCluster(t *testing.T) {
v, err := semver.NewVersion("1.9")
assert.NoError(t, err)
c := cache.NewCluster(v)

v1 := c.ListVersion()
c := cache.NewCluster(v)
v1, err := c.ListVersion()
assert.NoError(t, err)
assert.Equal(t, v, v1)
}
6 changes: 1 addition & 5 deletions internal/dag/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ func ListVersion(ctx context.Context) (*semver.Version, error) {
if err != nil {
return nil, err
}
rev, err := semver.NewVersion(info.Major + "." + info.Minor)
if err != nil {
return nil, err
}

return rev, nil
return ParseVersion(info)
}
37 changes: 37 additions & 0 deletions internal/dag/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,49 @@
package dag

import (
"errors"
"fmt"
"testing"

"github.com/Masterminds/semver"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/version"
)

func TestParseVers(t *testing.T) {
v, _ := semver.NewVersion("1.28")

uu := map[string]struct {
info version.Info
err error
ver *semver.Version
}{
"empty": {
err: fmt.Errorf(`semver parse failed for "." (""|""): %w`, errors.New("Invalid Semantic Version")),
},
"happy": {
info: version.Info{Major: "1", Minor: "28"},
ver: v,
},
"extras": {
info: version.Info{Major: "1", Minor: "28+"},
ver: v,
},
}

for k := range uu {
u := uu[k]
t.Run(k, func(t *testing.T) {
v, err := ParseVersion(&u.info)
assert.Equal(t, u.err, err)
if err == nil {
assert.Equal(t, u.ver, v)
}
})
}
}

func TestMetaFQN(t *testing.T) {
uu := []struct {
m metav1.ObjectMeta
Expand Down
18 changes: 18 additions & 0 deletions internal/dag/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,30 @@ package dag

import (
"context"
"fmt"
"strings"

"github.com/Masterminds/semver"
"github.com/derailed/popeye/internal"
"github.com/derailed/popeye/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/version"
)

// ParseVersion renders cluster info version into semver rev.
func ParseVersion(info *version.Info) (*semver.Version, error) {
if info == nil {
return nil, fmt.Errorf("no cluster version available")
}
v := strings.TrimSuffix(info.Major+"."+info.Minor, "+")
rev, err := semver.NewVersion(v)
if err != nil {
err = fmt.Errorf("semver parse failed for %q (%q|%q): %w", v, info.Major, info.Minor, err)
}

return rev, err
}

func mustExtractFactory(ctx context.Context) types.Factory {
f, ok := ctx.Value(internal.KeyFactory).(types.Factory)
if !ok {
Expand Down
7 changes: 5 additions & 2 deletions internal/lint/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type (

// ClusterLister list available Clusters on a cluster.
ClusterLister interface {
ListVersion() *semver.Version
ListVersion() (*semver.Version, error)
HasMetrics() bool
}
)
Expand All @@ -44,7 +44,10 @@ func (c *Cluster) Lint(ctx context.Context) error {
}

func (c *Cluster) checkVersion(ctx context.Context) error {
rev := c.ListVersion()
rev, err := c.ListVersion()
if err != nil {
return err
}

ctx = internal.WithSpec(ctx, specFor("Version", nil))
if rev.Major() != tolerableMajor || rev.Minor() < tolerableMinor {
Expand Down
21 changes: 18 additions & 3 deletions internal/lint/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (

"github.com/Masterminds/semver"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/version"

"github.com/derailed/popeye/internal/dag"
"github.com/derailed/popeye/internal/issues"
"github.com/derailed/popeye/internal/rules"
"github.com/derailed/popeye/internal/test"
Expand All @@ -34,6 +36,20 @@ func TestClusterLint(t *testing.T) {
},
},
},
"plus": {
major: "1", minor: "29+",
metrics: true,
e: map[string]issues.Issues{
"Version": {
{
GVR: "clusters",
Group: issues.Root,
Message: "[POP-406] K8s version OK",
Level: rules.OkLevel,
},
},
},
},
"gizzard": {
major: "1", minor: "11",
metrics: false,
Expand Down Expand Up @@ -76,9 +92,8 @@ func newMockCluster(major, minor string, metrics bool) mockCluster {
return mockCluster{major: major, minor: minor, metrics: metrics}
}

func (c mockCluster) ListVersion() *semver.Version {
v, _ := semver.NewVersion(c.major + "." + c.minor)
return v
func (c mockCluster) ListVersion() (*semver.Version, error) {
return dag.ParseVersion(&version.Info{Major: c.major, Minor: c.minor})
}

func (c mockCluster) HasMetrics() bool {
Expand Down
50 changes: 30 additions & 20 deletions internal/lint/ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/derailed/popeye/internal"
"github.com/derailed/popeye/internal/cache"
"github.com/derailed/popeye/internal/client"
"github.com/derailed/popeye/internal/db"
"github.com/derailed/popeye/internal/issues"
v1 "k8s.io/api/core/v1"
Expand All @@ -18,6 +19,7 @@ import (
// Namespace represents a Namespace linter.
type Namespace struct {
*issues.Collector

db *db.DB
}

Expand All @@ -29,26 +31,6 @@ func NewNamespace(co *issues.Collector, db *db.DB) *Namespace {
}
}

// ReferencedNamespaces fetch all namespaces referenced by pods and service accounts.
func (s *Namespace) ReferencedNamespaces(res map[string]struct{}) error {
var refs sync.Map
pod := cache.NewPod(s.db)
if err := pod.PodRefs(&refs); err != nil {
return err
}
sa := cache.NewServiceAccount(s.db)
if err := sa.ServiceAccountRefs(&refs); err != nil {
return err
}
if ss, ok := refs.Load("ns"); ok {
for ns := range ss.(internal.StringSet) {
res[ns] = struct{}{}
}
}

return nil
}

// Lint cleanse the resource.
func (s *Namespace) Lint(ctx context.Context) error {
used := make(map[string]struct{})
Expand All @@ -58,12 +40,20 @@ func (s *Namespace) Lint(ctx context.Context) error {
txn, it := s.db.MustITFor(internal.Glossary[internal.NS])
defer txn.Abort()

cns, ok := ctx.Value(internal.KeyNamespace).(string)
if !ok {
cns = client.BlankNamespace
}

for o := it.Next(); o != nil; o = it.Next() {
ns, ok := o.(*v1.Namespace)
if !ok {
return errors.New("expected ns")
}
fqn := ns.Name
if cns != client.BlankNamespace && fqn != cns {
continue
}
s.InitOutcome(fqn)
ctx = internal.WithSpec(ctx, specFor(fqn, ns))

Expand All @@ -77,6 +67,26 @@ func (s *Namespace) Lint(ctx context.Context) error {
return nil
}

// ReferencedNamespaces fetch all namespaces referenced by pods and service accounts.
func (s *Namespace) ReferencedNamespaces(res map[string]struct{}) error {
var refs sync.Map
pod := cache.NewPod(s.db)
if err := pod.PodRefs(&refs); err != nil {
return err
}
sa := cache.NewServiceAccount(s.db)
if err := sa.ServiceAccountRefs(&refs); err != nil {
return err
}
if ss, ok := refs.Load("ns"); ok {
for ns := range ss.(internal.StringSet) {
res[ns] = struct{}{}
}
}

return nil
}

func (s *Namespace) checkActive(ctx context.Context, p v1.NamespacePhase) bool {
if !isNSActive(p) {
s.AddCode(ctx, 800)
Expand Down
7 changes: 2 additions & 5 deletions internal/report/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,11 @@ func (b *Builder) PrintSummary(s *ScanReport) {

// PrintClusterInfo displays cluster information.
func (b *Builder) PrintClusterInfo(s *ScanReport, metrics bool) {
cl, ct := b.ClusterName, b.ContextName
cl := b.ClusterName
if cl == "" {
cl = "n/a"
}
if ct == "" {
ct = "n/a"
}
s.Open(Titleize(fmt.Sprintf("General [%s/%s] (%s)", cl, ct, b.Report.Timestamp), -1), nil)
s.Open(Titleize(fmt.Sprintf("General [%s] (%s)", cl, b.Report.Timestamp), -1), nil)
{
s.Print(rules.OkLevel, 1, "Connectivity")
if metrics {
Expand Down
Loading

0 comments on commit dd8eafd

Please sign in to comment.