Skip to content

Commit d8eacc0

Browse files
authored
Merge pull request #2 from raffis/next
Respect kustomization inventroy and namespace
2 parents 2109b23 + f469a7d commit d8eacc0

8 files changed

Lines changed: 228 additions & 369 deletions

File tree

.github/workflows/e2e.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,4 @@ jobs:
3535
git --no-pager diff
3636
echo 'run make test and commit changes'
3737
exit 1
38-
fi
39-
- name: Setup Kubernetes
40-
uses: engineerd/setup-kind@v0.5.0
41-
with:
42-
version: v0.11.1
43-
image: kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6
38+
fi

.github/workflows/release.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ permissions:
1414
id-token: write # needed for keyless signing
1515
packages: write # needed for ghcr access
1616

17-
env:
18-
APP: kjournal
19-
2017
jobs:
2118
build:
2219
name: Build

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
# GitOps zombies
22

3+
![Release](https://img.shields.io/github/v/release/raffis/gitops-zombies)
4+
[![release](https://github.com/raffis/gitops-zombies/actions/workflows/release.yaml/badge.svg)](https://github.com/raffis/gitops-zombies/actions/workflows/release.yaml)
5+
[![Go Report Card](https://goreportcard.com/badge/github.com/raffis/gitops-zombies)](https://goreportcard.com/report/github.com/raffis/gitops-zombies)
6+
[![Coverage Status](https://coveralls.io/repos/github/raffis/gitops-zombies/badge.svg?branch=main)](https://coveralls.io/github/raffis/gitops-zombies?branch=main)
7+
38
This simple tool will help you find kubernetes resources which are not managed via GitOps (flux2).
49

510
<p align="center"><img src="https://github.com/raffis/gitops-zombies/blob/main/assets/logo.png?raw=true" alt="logo"/></p>
611

712
## How does it work?
813

9-
It will discover all apis installed on a cluster and identify resources which are not part of a Kustomization or a HelmRelease.
10-
The app will also acknowledge the following things:
14+
gitops-zombies discovers all apis installed on a cluster and identify resources which are not part of a Kustomization or a HelmRelease.
15+
It also acknowledges the following facts:
1116

1217
* Ignores resources which are owned by a parent resource (For example pods which are created by a deployment)
1318
* Ignores resources which are considered dynamic (metrics, leases, events, endpoints, ...)
1419
* Filter out resources which are created by the apiserver itself (like default rbacs)
1520
* Filters secrets which are managed by other parties including helm or ServiceAccount tokens
1621
* Checks if the referenced HelmRelease or Kustomization exists
22+
* Checks if resources are still part of the kustomization inventory
1723

1824

1925
## How do I install it?

cmd/main.go

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@ import (
77
"strings"
88
"sync"
99

10-
"gihub.com/raffis/flux-zombies/pkg/collector"
10+
"gihub.com/raffis/gitops-zombies/pkg/collector"
11+
ksapi "github.com/fluxcd/kustomize-controller/api/v1beta2"
1112
"github.com/spf13/cobra"
1213
"golang.org/x/exp/slices"
1314
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1415
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
16+
"k8s.io/apimachinery/pkg/runtime"
1517
"k8s.io/apimachinery/pkg/runtime/schema"
18+
"k8s.io/apimachinery/pkg/runtime/serializer"
1619
"k8s.io/cli-runtime/pkg/genericclioptions"
1720
"k8s.io/client-go/discovery"
1821
"k8s.io/client-go/dynamic"
22+
"k8s.io/client-go/rest"
1923
k8sget "k8s.io/kubectl/pkg/cmd/get"
2024
)
2125

@@ -84,11 +88,6 @@ func main() {
8488
os.Exit(1)
8589
}
8690

87-
var (
88-
helmReleases []unstructured.Unstructured
89-
kustomizations []unstructured.Unstructured
90-
)
91-
9291
func run(cmd *cobra.Command, args []string) error {
9392
if flags.version {
9493
fmt.Printf(`{"version":"%s","sha":"%s","date":"%s"}`+"\n", version, commit, date)
@@ -105,6 +104,8 @@ func run(cmd *cobra.Command, args []string) error {
105104
return err
106105
}
107106

107+
cfg.WarningHandler = rest.NoWarnings{}
108+
108109
disc, err := discovery.NewDiscoveryClientForConfig(cfg)
109110
if err != nil {
110111
return err
@@ -115,12 +116,24 @@ func run(cmd *cobra.Command, args []string) error {
115116
return err
116117
}
117118

118-
client, err := dynamic.NewForConfig(cfg)
119+
dynClient, err := dynamic.NewForConfig(cfg)
120+
if err != nil {
121+
return err
122+
}
123+
124+
cfg.GroupVersion = &ksapi.GroupVersion
125+
var scheme = runtime.NewScheme()
126+
ksapi.AddToScheme(scheme)
127+
var codecs = serializer.NewCodecFactory(scheme)
128+
cfg.NegotiatedSerializer = codecs.WithoutConversion()
129+
cfg.APIPath = "/apis"
130+
131+
structClient, err := rest.RESTClientFor(cfg)
119132
if err != nil {
120133
return err
121134
}
122135

123-
helmReleases, err = listResources(context.TODO(), client.Resource(schema.GroupVersionResource{
136+
helmReleases, err := listResources(context.TODO(), dynClient.Resource(schema.GroupVersionResource{
124137
Group: "helm.toolkit.fluxcd.io",
125138
Version: "v2beta1",
126139
Resource: "helmreleases",
@@ -130,12 +143,7 @@ func run(cmd *cobra.Command, args []string) error {
130143
return fmt.Errorf("failed to get helmreleases: %w", err)
131144
}
132145

133-
kustomizations, err = listResources(context.TODO(), client.Resource(schema.GroupVersionResource{
134-
Group: "kustomize.toolkit.fluxcd.io",
135-
Version: "v1beta2",
136-
Resource: "kustomizations",
137-
}))
138-
146+
kustomizations, err := listKustomizations(context.TODO(), structClient)
139147
if err != nil {
140148
return fmt.Errorf("failed to get kustomizations: %w", err)
141149
}
@@ -163,6 +171,11 @@ func run(cmd *cobra.Command, args []string) error {
163171
for _, resource := range group.APIResources {
164172
logger.Debugf("discover resource %#v.%#v.%#v", resource.Name, resource.Group, resource.Version)
165173

174+
if *kubeconfigArgs.Namespace != "" && !resource.Namespaced {
175+
logger.Debugf("skipping cluster scoped resource %#v.%#v.%#v, namespaced scope was requested", resource.Name, resource.Group, resource.Version)
176+
continue
177+
}
178+
166179
gvr := schema.GroupVersionResource{
167180
Group: gv.Group,
168181
Version: gv.Version,
@@ -177,7 +190,7 @@ func run(cmd *cobra.Command, args []string) error {
177190
}
178191
}
179192

180-
resAPI := client.Resource(gvr)
193+
resAPI := dynClient.Resource(gvr).Namespace(*kubeconfigArgs.Namespace)
181194

182195
// Skip APIS which do not support list
183196
if !slices.Contains(resource.Verbs, "list") {
@@ -190,7 +203,7 @@ func run(cmd *cobra.Command, args []string) error {
190203
defer wgProducer.Done()
191204

192205
if err := handleResource(context.TODO(), discover, resAPI, ch); err != nil {
193-
logger.Failuref("could not hanlder resource: %s", err)
206+
logger.Failuref("could not handle resource: %s", err)
194207
}
195208
}(resAPI)
196209
}
@@ -221,6 +234,22 @@ func listResources(ctx context.Context, resAPI dynamic.ResourceInterface) (items
221234
return list.Items, err
222235
}
223236

237+
func listKustomizations(ctx context.Context, client *rest.RESTClient) (items []ksapi.Kustomization, err error) {
238+
ks := &ksapi.KustomizationList{}
239+
240+
r := client.
241+
Get().
242+
Resource("kustomizations").
243+
Do(ctx)
244+
245+
err = r.Into(ks)
246+
if err != nil {
247+
return []ksapi.Kustomization{}, err
248+
}
249+
250+
return ks.Items, err
251+
}
252+
224253
func getLabelSelector() string {
225254
selector := ""
226255
if !flags.includeAll {

go.mod

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
module gihub.com/raffis/flux-zombies
1+
module gihub.com/raffis/gitops-zombies
22

33
go 1.18
44

55
require (
6+
github.com/fluxcd/kustomize-controller/api v0.30.0
67
github.com/spf13/cobra v1.5.0
78
golang.org/x/exp v0.0.0-20221004215720-b9f4876ce741
89
gotest.tools/v3 v3.0.3
9-
k8s.io/apimachinery v0.25.2
10-
k8s.io/cli-runtime v0.25.2
11-
k8s.io/client-go v0.25.2
10+
k8s.io/apimachinery v0.25.3
11+
k8s.io/cli-runtime v0.25.3
12+
k8s.io/client-go v0.25.3
1213
k8s.io/kubectl v0.25.2
1314
)
1415

@@ -20,8 +21,10 @@ require (
2021
github.com/chai2010/gettext-go v1.0.2 // indirect
2122
github.com/davecgh/go-spew v1.1.1 // indirect
2223
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
23-
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
24+
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
2425
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
26+
github.com/fluxcd/pkg/apis/kustomize v0.6.0 // indirect
27+
github.com/fluxcd/pkg/apis/meta v0.17.0 // indirect
2528
github.com/fvbommel/sortorder v1.0.1 // indirect
2629
github.com/go-errors/errors v1.0.1 // indirect
2730
github.com/go-logr/logr v1.2.3 // indirect
@@ -32,49 +35,55 @@ require (
3235
github.com/golang/protobuf v1.5.2 // indirect
3336
github.com/google/btree v1.0.1 // indirect
3437
github.com/google/gnostic v0.5.7-v3refs // indirect
35-
github.com/google/go-cmp v0.5.8 // indirect
36-
github.com/google/gofuzz v1.1.0 // indirect
38+
github.com/google/go-cmp v0.5.9 // indirect
39+
github.com/google/gofuzz v1.2.0 // indirect
3740
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
38-
github.com/google/uuid v1.1.2 // indirect
41+
github.com/google/uuid v1.3.0 // indirect
3942
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
40-
github.com/imdario/mergo v0.3.6 // indirect
43+
github.com/imdario/mergo v0.3.12 // indirect
4144
github.com/inconshreveable/mousetrap v1.0.0 // indirect
4245
github.com/josharian/intern v1.0.0 // indirect
4346
github.com/json-iterator/go v1.1.12 // indirect
47+
github.com/kr/pretty v0.2.1 // indirect
4448
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
4549
github.com/mailru/easyjson v0.7.6 // indirect
46-
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
50+
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
4751
github.com/moby/spdystream v0.2.0 // indirect
4852
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
4953
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5054
github.com/modern-go/reflect2 v1.0.2 // indirect
5155
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
5256
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
57+
github.com/onsi/ginkgo/v2 v2.3.0 // indirect
58+
github.com/onsi/gomega v1.22.1 // indirect
5359
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
5460
github.com/pkg/errors v0.9.1 // indirect
5561
github.com/russross/blackfriday v1.5.2 // indirect
5662
github.com/spf13/pflag v1.0.5 // indirect
63+
github.com/stretchr/objx v0.3.0 // indirect
5764
github.com/xlab/treeprint v1.1.0 // indirect
5865
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
59-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
60-
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
61-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
62-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
63-
golang.org/x/text v0.3.7 // indirect
64-
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
66+
golang.org/x/net v0.1.0 // indirect
67+
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
68+
golang.org/x/sys v0.1.0 // indirect
69+
golang.org/x/term v0.1.0 // indirect
70+
golang.org/x/text v0.4.0 // indirect
71+
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
6572
google.golang.org/appengine v1.6.7 // indirect
66-
google.golang.org/protobuf v1.28.0 // indirect
73+
google.golang.org/protobuf v1.28.1 // indirect
6774
gopkg.in/inf.v0 v0.9.1 // indirect
6875
gopkg.in/yaml.v2 v2.4.0 // indirect
6976
gopkg.in/yaml.v3 v3.0.1 // indirect
70-
k8s.io/api v0.25.2 // indirect
71-
k8s.io/component-base v0.25.2 // indirect
72-
k8s.io/klog/v2 v2.70.1 // indirect
77+
k8s.io/api v0.25.3 // indirect
78+
k8s.io/apiextensions-apiserver v0.25.3 // indirect
79+
k8s.io/component-base v0.25.3 // indirect
80+
k8s.io/klog/v2 v2.80.1 // indirect
7381
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
74-
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
82+
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 // indirect
83+
sigs.k8s.io/controller-runtime v0.13.0 // indirect
7584
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
7685
sigs.k8s.io/kustomize/api v0.12.1 // indirect
7786
sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect
7887
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
79-
sigs.k8s.io/yaml v1.2.0 // indirect
88+
sigs.k8s.io/yaml v1.3.0 // indirect
8089
)

0 commit comments

Comments
 (0)