Skip to content

Commit 5347cc2

Browse files
committed
release v0.20.5
2 parents 9e4687d + 6a1bf98 commit 5347cc2

File tree

14 files changed

+145
-105
lines changed

14 files changed

+145
-105
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
NAME := popeye
22
PACKAGE := github.com/derailed/$(NAME)
3-
VERSION := v0.20.4
3+
VERSION := v0.20.5
44
GIT := $(shell git rev-parse --short HEAD)
55
DATE := $(shell date +%FT%T%Z)
66
IMG_NAME := derailed/popeye

change_logs/release_v0.20.5.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<img src="https://raw.githubusercontent.com/derailed/popeye/master/assets/popeye_logo.png" align="right" width="200" height="auto"/>
2+
3+
# Release v0.20.5
4+
5+
## Notes
6+
7+
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!
8+
9+
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.
10+
11+
Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
12+
13+
---
14+
15+
## Maintenance Release
16+
17+
---
18+
19+
## Resolved Issues
20+
21+
. [#290](https://github.com/derailed/popeye/issues/290) Secrets is not scanned on Openshift 4.12 bug
22+
. [#289](https://github.com/derailed/popeye/issues/289) "No associated endpoint" (POP-1105) reported for service question
23+
. [#288](https://github.com/derailed/popeye/issues/288) A Score granted despite no resources being scanned
24+
25+
---
26+
27+
<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)

internal/client/client.go

+33-19
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,18 @@ func InitConnectionOrDie(config types.Config) (*APIClient, error) {
6464
config: config,
6565
cache: cache.NewLRUExpireCache(cacheSize),
6666
}
67+
_, err := a.serverGroups()
68+
if err != nil {
69+
return nil, err
70+
}
6771
if err := a.supportsMetricsResources(); err != nil {
68-
log.Warn().Msgf("no metrics server detected %s", err.Error())
72+
log.Warn().Err(err).Msgf("no metrics server detected")
6973
}
7074

7175
return &a, nil
7276
}
7377

74-
func makeSAR(ns string, gvr types.GVR) *authorizationv1.SelfSubjectAccessReview {
78+
func makeSAR(ns string, gvr types.GVR, n string) *authorizationv1.SelfSubjectAccessReview {
7579
if ns == "-" {
7680
ns = ""
7781
}
@@ -83,13 +87,14 @@ func makeSAR(ns string, gvr types.GVR) *authorizationv1.SelfSubjectAccessReview
8387
Group: res.Group,
8488
Resource: res.Resource,
8589
Subresource: gvr.SubResource(),
90+
Name: n,
8691
},
8792
},
8893
}
8994
}
9095

91-
func makeCacheKey(ns, gvr string, vv []string) string {
92-
return ns + ":" + gvr + "::" + strings.Join(vv, ",")
96+
func makeCacheKey(ns string, gvr types.GVR, n string, vv []string) string {
97+
return ns + ":" + gvr.String() + ":" + n + "::" + strings.Join(vv, ",")
9398
}
9499

95100
// ActiveContext returns the current context name.
@@ -146,11 +151,11 @@ func (a *APIClient) ConnectionOK() bool {
146151
}
147152

148153
// CanI checks if user has access to a certain resource.
149-
func (a *APIClient) CanI(ns string, gvr types.GVR, verbs ...string) (auth bool, err error) {
154+
func (a *APIClient) CanI(ns string, gvr types.GVR, n string, verbs []string) (auth bool, err error) {
150155
if IsClusterWide(ns) {
151-
ns = AllNamespaces
156+
ns = BlankNamespace
152157
}
153-
key := makeCacheKey(ns, gvr.String(), verbs)
158+
key := makeCacheKey(ns, gvr, n, verbs)
154159
if v, ok := a.cache.Get(key); ok {
155160
if auth, ok = v.(bool); ok {
156161
return auth, nil
@@ -161,7 +166,7 @@ func (a *APIClient) CanI(ns string, gvr types.GVR, verbs ...string) (auth bool,
161166
if err != nil {
162167
return false, err
163168
}
164-
dial, sar := c.AuthorizationV1().SelfSubjectAccessReviews(), makeSAR(ns, gvr)
169+
dial, sar := c.AuthorizationV1().SelfSubjectAccessReviews(), makeSAR(ns, gvr, n)
165170
ctx, cancel := context.WithTimeout(context.Background(), CallTimeout)
166171
defer cancel()
167172
for _, v := range verbs {
@@ -357,30 +362,38 @@ func (a *APIClient) checkCacheBool(key string) (state bool, ok bool) {
357362
return
358363
}
359364

365+
func (a *APIClient) serverGroups() (*metav1.APIGroupList, error) {
366+
dial, err := a.CachedDiscovery()
367+
if err != nil {
368+
log.Warn().Err(err).Msgf("Unable to dial discovery API")
369+
return nil, err
370+
}
371+
apiGroups, err := dial.ServerGroups()
372+
if err != nil {
373+
log.Warn().Err(err).Msgf("Unable to retrieve server groups")
374+
return nil, fmt.Errorf("unable to fetch server groups: %w", err)
375+
}
376+
377+
return apiGroups, nil
378+
}
379+
360380
func (a *APIClient) supportsMetricsResources() error {
361381
supported, ok := a.checkCacheBool(cacheMXAPIKey)
362382
if ok {
363383
if supported {
364384
return nil
365385
}
366-
return errors.New("No metrics-server detected")
386+
return errors.New("no metrics-server detected")
367387
}
368-
369388
defer func() {
370389
a.cache.Add(cacheMXAPIKey, supported, cacheExpiry)
371390
}()
372391

373-
dial, err := a.CachedDiscovery()
374-
if err != nil {
375-
log.Warn().Err(err).Msgf("Unable to dial discovery API")
376-
return err
377-
}
378-
apiGroups, err := dial.ServerGroups()
392+
gg, err := a.serverGroups()
379393
if err != nil {
380-
log.Warn().Err(err).Msgf("Unable to retrieve server groups")
381394
return err
382395
}
383-
for _, grp := range apiGroups.Groups {
396+
for _, grp := range gg.Groups {
384397
if grp.Name != metricsapi.GroupName {
385398
continue
386399
}
@@ -390,8 +403,9 @@ func (a *APIClient) supportsMetricsResources() error {
390403
}
391404
}
392405

393-
return errors.New("No metrics-server detected")
406+
return errors.New("no metrics-server detected")
394407
}
408+
395409
func checkMetricsVersion(grp metav1.APIGroup) bool {
396410
for _, version := range grp.Versions {
397411
for _, supportedVersion := range supportedMetricsAPIVersions {

internal/client/config.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func (c *Config) CurrentUserName() (string, error) {
234234

235235
// CurrentNamespaceName retrieves the active namespace.
236236
func (c *Config) CurrentNamespaceName() (string, error) {
237-
if c.flags.Namespace != nil {
237+
if isSet(c.flags.Namespace) {
238238
return *c.flags.Namespace, nil
239239
}
240240

internal/client/factory.go

+49-37
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (f *Factory) Start(ns string) {
5050
}
5151
}
5252

53-
// Terminate stops the factory.
53+
// Terminate terminates all watchers and forwards.
5454
func (f *Factory) Terminate() {
5555
f.mx.Lock()
5656
defer f.mx.Unlock()
@@ -66,48 +66,68 @@ func (f *Factory) Terminate() {
6666

6767
// List returns a resource collection.
6868
func (f *Factory) List(gvr types.GVR, ns string, wait bool, labels labels.Selector) ([]runtime.Object, error) {
69-
inf, err := f.CanForResource(ns, gvr, types.MonitorAccess...)
69+
inf, err := f.CanForResource(ns, gvr, types.ListAccess)
7070
if err != nil {
7171
return nil, err
7272
}
73-
if wait {
74-
f.waitForCacheSync(ns)
73+
if IsAllNamespace(ns) {
74+
ns = BlankNamespace
7575
}
76+
77+
var oo []runtime.Object
7678
if IsClusterScoped(ns) {
77-
return inf.Lister().List(labels)
79+
oo, err = inf.Lister().List(labels)
80+
} else {
81+
oo, err = inf.Lister().ByNamespace(ns).List(labels)
82+
}
83+
if !wait || (wait && inf.Informer().HasSynced()) {
84+
return oo, err
7885
}
7986

80-
if IsAllNamespace(ns) {
81-
ns = AllNamespaces
87+
f.waitForCacheSync(ns)
88+
if IsClusterScoped(ns) {
89+
return inf.Lister().List(labels)
8290
}
8391
return inf.Lister().ByNamespace(ns).List(labels)
8492
}
8593

94+
// HasSynced checks if given informer is up to date.
95+
func (f *Factory) HasSynced(gvr types.GVR, ns string) (bool, error) {
96+
inf, err := f.CanForResource(ns, gvr, types.ListAccess)
97+
if err != nil {
98+
return false, err
99+
}
100+
101+
return inf.Informer().HasSynced(), nil
102+
}
103+
86104
// Get retrieves a given resource.
87-
func (f *Factory) Get(gvr types.GVR, path string, wait bool, sel labels.Selector) (runtime.Object, error) {
88-
ns, n := Namespaced(path)
89-
inf, err := f.CanForResource(ns, gvr, types.GetVerb)
105+
func (f *Factory) Get(gvr types.GVR, fqn string, wait bool, sel labels.Selector) (runtime.Object, error) {
106+
ns, n := Namespaced(fqn)
107+
inf, err := f.CanForResource(ns, gvr, []string{types.GetVerb})
90108
if err != nil {
91109
return nil, err
92110
}
93-
94-
if wait {
95-
f.waitForCacheSync(ns)
111+
var o runtime.Object
112+
if IsClusterScoped(ns) {
113+
o, err = inf.Lister().Get(n)
114+
} else {
115+
o, err = inf.Lister().ByNamespace(ns).Get(n)
116+
}
117+
if !wait || (wait && inf.Informer().HasSynced()) {
118+
return o, err
96119
}
120+
121+
f.waitForCacheSync(ns)
97122
if IsClusterScoped(ns) {
98123
return inf.Lister().Get(n)
99124
}
100-
101125
return inf.Lister().ByNamespace(ns).Get(n)
102126
}
103127

104128
func (f *Factory) waitForCacheSync(ns string) {
105129
if IsClusterWide(ns) {
106-
ns = AllNamespaces
107-
}
108-
109-
if f.isClusterWide() {
110-
ns = AllNamespaces
130+
ns = BlankNamespace
111131
}
112132

113133
f.mx.RLock()
@@ -131,7 +151,7 @@ func (f *Factory) WaitForCacheSync() {
131151
for ns, fac := range f.factories {
132152
m := fac.WaitForCacheSync(f.stopChan)
133153
for k, v := range m {
134-
log.Debug().Msgf("CACHE %q synched %t:%s", ns, v, k)
154+
log.Debug().Msgf("CACHE `%q Loaded %t:%s", ns, v, k)
135155
}
136156
}
137157
}
@@ -148,33 +168,24 @@ func (f *Factory) FactoryFor(ns string) di.DynamicSharedInformerFactory {
148168

149169
// SetActiveNS sets the active namespace.
150170
func (f *Factory) SetActiveNS(ns string) error {
151-
if !f.isClusterWide() {
152-
if _, err := f.ensureFactory(ns); err != nil {
153-
return err
154-
}
171+
if f.isClusterWide() {
172+
return nil
155173
}
156-
157-
return nil
174+
_, err := f.ensureFactory(ns)
175+
return err
158176
}
159177

160178
func (f *Factory) isClusterWide() bool {
161179
f.mx.RLock()
162180
defer f.mx.RUnlock()
181+
_, ok := f.factories[BlankNamespace]
163182

164-
_, ok := f.factories[AllNamespaces]
165183
return ok
166184
}
167185

168186
// CanForResource return an informer is user has access.
169-
func (f *Factory) CanForResource(ns string, gvr types.GVR, verbs ...string) (informers.GenericInformer, error) {
170-
// If user can access resource cluster wide, prefer cluster wide factory.
171-
if !IsClusterWide(ns) {
172-
auth, err := f.Client().CanI(AllNamespaces, gvr, verbs...)
173-
if auth && err == nil {
174-
return f.ForResource(AllNamespaces, gvr)
175-
}
176-
}
177-
auth, err := f.Client().CanI(ns, gvr, verbs...)
187+
func (f *Factory) CanForResource(ns string, gvr types.GVR, verbs []string) (informers.GenericInformer, error) {
188+
auth, err := f.Client().CanI(ns, gvr, "", verbs)
178189
if err != nil {
179190
return nil, err
180191
}
@@ -206,13 +217,14 @@ func (f *Factory) ForResource(ns string, gvr types.GVR) (informers.GenericInform
206217

207218
func (f *Factory) ensureFactory(ns string) (di.DynamicSharedInformerFactory, error) {
208219
if IsClusterWide(ns) {
209-
ns = AllNamespaces
220+
ns = BlankNamespace
210221
}
211222
f.mx.Lock()
212223
defer f.mx.Unlock()
213224
if fac, ok := f.factories[ns]; ok {
214225
return fac, nil
215226
}
227+
216228
dial, err := f.client.DynDial()
217229
if err != nil {
218230
return nil, err

internal/client/helpers.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ var toFileName = regexp.MustCompile(`[^(\w/\.)]`)
1717

1818
// IsClusterWide returns true if ns designates cluster scope, false otherwise.
1919
func IsClusterWide(ns string) bool {
20-
return ns == NamespaceAll || ns == AllNamespaces || ns == ClusterScope
20+
return ns == NamespaceAll || ns == BlankNamespace || ns == ClusterScope
2121
}
2222

2323
// CleanseNamespace ensures all ns maps to blank.
2424
func CleanseNamespace(ns string) string {
2525
if IsAllNamespace(ns) {
26-
return AllNamespaces
26+
return BlankNamespace
2727
}
2828

2929
return ns
@@ -36,7 +36,7 @@ func IsAllNamespace(ns string) bool {
3636

3737
// IsAllNamespaces returns true if all namespaces, false otherwise.
3838
func IsAllNamespaces(ns string) bool {
39-
return ns == NamespaceAll || ns == AllNamespaces
39+
return ns == NamespaceAll || ns == BlankNamespace
4040
}
4141

4242
// IsNamespaced returns true if a specific ns is given.

0 commit comments

Comments
 (0)