Skip to content

Commit 7f96fe2

Browse files
committed
remove gabs as a dependency
Signed-off-by: Tim Ramlot <[email protected]>
1 parent 2ebec9e commit 7f96fe2

File tree

4 files changed

+76
-136
lines changed

4 files changed

+76
-136
lines changed

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ module github.com/jetstack/preflight
33
go 1.22.0
44

55
require (
6-
github.com/Jeffail/gabs/v2 v2.7.0
76
github.com/cenkalti/backoff v2.2.1+incompatible
87
github.com/d4l3k/messagediff v1.2.1
98
github.com/fatih/color v1.17.0
109
github.com/google/uuid v1.6.0
1110
github.com/hashicorp/go-multierror v1.1.1
1211
github.com/jetstack/venafi-connection-lib v0.1.1-0.20240909145535-cd2301fd4e7c
13-
github.com/json-iterator/go v1.1.12
1412
github.com/maxatome/go-testdeep v1.14.0
1513
github.com/microcosm-cc/bluemonday v1.0.27
1614
github.com/pkg/errors v0.9.1
@@ -44,6 +42,7 @@ require (
4442
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
4543
github.com/gorilla/css v1.0.1 // indirect
4644
github.com/gorilla/websocket v1.5.1 // indirect
45+
github.com/json-iterator/go v1.1.12 // indirect
4746
github.com/klauspost/compress v1.17.9 // indirect
4847
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4948
github.com/sosodev/duration v1.2.0 // indirect

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
github.com/Jeffail/gabs/v2 v2.7.0 h1:Y2edYaTcE8ZpRsR2AtmPu5xQdFDIthFG0jYhu5PY8kg=
2-
github.com/Jeffail/gabs/v2 v2.7.0/go.mod h1:dp5ocw1FvBBQYssgHsG7I1WYsiLRtkUaB1FEtSwvNUw=
31
github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w=
42
github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM=
53
github.com/Venafi/vcert/v5 v5.7.1 h1:gUDbSuP6NE4yAslWp+D+ZoJlYOSRWhQora48oExuEN4=

pkg/datagatherer/k8s/fieldfilter.go

Lines changed: 57 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,88 @@
11
package k8s
22

33
import (
4-
"fmt"
5-
"strings"
6-
7-
"github.com/Jeffail/gabs/v2"
8-
json "github.com/json-iterator/go"
94
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
105
)
116

127
// SecretSelectedFields is the list of fields sent from Secret objects to the
138
// backend
14-
var SecretSelectedFields = []string{
15-
"kind",
16-
"apiVersion",
17-
"metadata.annotations",
18-
"metadata.labels",
19-
"metadata.name",
20-
"metadata.namespace",
21-
"metadata.ownerReferences",
22-
"metadata.selfLink",
23-
"metadata.uid",
24-
"type",
25-
"/data/tls.crt",
26-
"/data/ca.crt",
9+
var SecretSelectedFields = []FieldPath{
10+
{"kind"},
11+
{"apiVersion"},
12+
{"metadata", "annotations"},
13+
{"metadata", "labels"},
14+
{"metadata", "name"},
15+
{"metadata", "namespace"},
16+
{"metadata", "ownerReferences"},
17+
{"metadata", "selfLink"},
18+
{"metadata", "uid"},
19+
20+
{"type"},
21+
{"data", "tls.crt"},
22+
{"data", "ca.crt"},
2723
}
2824

2925
// RouteSelectedFields is the list of fields sent from OpenShift Route objects to the
3026
// backend
31-
var RouteSelectedFields = []string{
32-
"kind",
33-
"apiVersion",
34-
"metadata.annotations",
35-
"metadata.name",
36-
"metadata.namespace",
37-
"metadata.ownerReferences",
38-
"metadata.selfLink",
39-
"metadata.uid",
40-
"spec.host",
41-
"spec.to.kind",
42-
"spec.to.port",
43-
"spec.to.name",
44-
"spec.to.weight",
45-
"spec.tls.termination",
46-
"spec.tls.certificate",
47-
"spec.tls.caCertificate",
48-
"spec.tls.destinationCACertificate",
49-
"spec.tls.insecureEdgeTerminationPolicy",
50-
"spec.wildcardPolicy",
51-
"status",
27+
var RouteSelectedFields = []FieldPath{
28+
{"kind"},
29+
{"apiVersion"},
30+
{"metadata", "annotations"},
31+
{"metadata", "name"},
32+
{"metadata", "namespace"},
33+
{"metadata", "ownerReferences"},
34+
{"metadata", "selfLink"},
35+
{"metadata", "uid"},
36+
37+
{"spec", "host"},
38+
{"spec", "to", "kind"},
39+
{"spec", "to", "name"},
40+
{"spec", "to", "weight"},
41+
{"spec", "tls", "termination"},
42+
{"spec", "tls", "certificate"},
43+
{"spec", "tls", "caCertificate"},
44+
{"spec", "tls", "destinationCACertificate"},
45+
{"spec", "tls", "insecureEdgeTerminationPolicy"},
46+
{"spec", "wildcardPolicy"},
47+
{"status"},
5248
}
5349

5450
// RedactFields are removed from all objects
55-
var RedactFields = []string{
56-
"metadata.managedFields",
57-
"/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration",
51+
var RedactFields = []FieldPath{
52+
{"metadata", "managedFields"},
53+
{"metadata", "annotations", "kubectl.kubernetes.io/last-applied-configuration"},
5854
}
5955

60-
// Select removes all but the supplied fields from the resource
61-
func Select(fields []string, resource *unstructured.Unstructured) error {
62-
// convert the object to JSON for field filtering
63-
asJSON, err := json.Marshal(resource)
64-
if err != nil {
65-
return fmt.Errorf("failed to marshal json for resource: %s", err)
66-
}
56+
type FieldPath []string
6757

68-
// parse the JSON for processing in gabs
69-
jsonParsed, err := gabs.ParseJSON(asJSON)
70-
if err != nil {
71-
return fmt.Errorf("failed to parse generated json for resource: %s", err)
58+
// Select removes all but the supplied fields from the resource
59+
func Select(fields []FieldPath, resource *unstructured.Unstructured) error {
60+
newResource := unstructured.Unstructured{
61+
Object: map[string]interface{}{},
7262
}
7363

74-
// craft a new object containing only selected fields
75-
filteredObject := gabs.New()
76-
for _, v := range fields {
77-
// also support JSONPointers for keys containing '.' chars
78-
if strings.HasPrefix(v, "/") {
79-
gObject, err := jsonParsed.JSONPointer(v)
80-
if err != nil {
81-
// fail to select field if missing, just continue
82-
continue
83-
}
84-
pathComponents, err := gabs.JSONPointerToSlice(v)
85-
if err != nil {
86-
return fmt.Errorf("invalid JSONPointer: %s", v)
87-
}
88-
filteredObject.Set(gObject.Data(), pathComponents...)
89-
} else {
90-
if jsonParsed.ExistsP(v) {
91-
filteredObject.SetP(jsonParsed.Path(v).Data(), v)
92-
}
64+
for _, field := range fields {
65+
value, found, err := unstructured.NestedFieldNoCopy(resource.Object, field...)
66+
if err != nil {
67+
return err
68+
}
69+
if !found {
70+
continue
71+
}
72+
if err := unstructured.SetNestedField(newResource.Object, value, field...); err != nil {
73+
return err
9374
}
9475
}
9576

96-
// load the filtered JSON back into the resource
97-
err = json.Unmarshal(filteredObject.Bytes(), resource)
98-
if err != nil {
99-
return fmt.Errorf("failed to update resource: %s", err)
100-
}
77+
resource.Object = newResource.Object
10178

10279
return nil
10380
}
10481

10582
// Redact removes the supplied fields from the resource
106-
func Redact(fields []string, resource *unstructured.Unstructured) error {
107-
// convert the object to JSON for field filtering
108-
asJSON, err := json.Marshal(resource)
109-
if err != nil {
110-
return fmt.Errorf("failed to marshal json for resource: %s", err)
111-
}
112-
113-
// parse the JSON for processing in gabs
114-
jsonParsed, err := gabs.ParseJSON(asJSON)
115-
if err != nil {
116-
return fmt.Errorf("failed to parse generated json for resource: %s", err)
117-
}
118-
119-
// craft a new object excluding redacted fields
120-
for _, v := range fields {
121-
// also support JSONPointers for keys containing '.' chars
122-
if strings.HasPrefix(v, "/") {
123-
pathComponents, err := gabs.JSONPointerToSlice(v)
124-
if err != nil {
125-
return fmt.Errorf("invalid JSONPointer: %s", v)
126-
}
127-
if jsonParsed.Exists(pathComponents...) {
128-
jsonParsed.Delete(pathComponents...)
129-
}
130-
} else {
131-
if jsonParsed.ExistsP(v) {
132-
jsonParsed.DeleteP(v)
133-
}
134-
}
135-
}
136-
137-
// load the filtered JSON back into the resource
138-
err = json.Unmarshal(jsonParsed.Bytes(), resource)
139-
if err != nil {
140-
return fmt.Errorf("failed to update resource: %s", err)
83+
func Redact(fields []FieldPath, resource *unstructured.Unstructured) error {
84+
for _, field := range fields {
85+
unstructured.RemoveNestedField(resource.Object, field...)
14186
}
14287

14388
return nil

pkg/datagatherer/k8s/fieldfilter_test.go

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ func TestSelect(t *testing.T) {
1818
"metadata": map[string]interface{}{
1919
"name": "example",
2020
"namespace": "example",
21-
"annotations": map[string]string{
21+
"annotations": map[string]interface{}{
2222
"kubectl.kubernetes.io/last-applied-configuration": "secret",
2323
},
24-
"labels": map[string]string{
24+
"labels": map[string]interface{}{
2525
"foo": "bar",
2626
},
2727
},
@@ -61,16 +61,16 @@ func TestSelect(t *testing.T) {
6161
"kind": "Route",
6262
"metadata": map[string]interface{}{
6363
"name": "example",
64-
"annotations": map[string]string{
64+
"annotations": map[string]interface{}{
6565
"kubectl.kubernetes.io/last-applied-configuration": "secret",
6666
},
67-
"labels": map[string]string{
67+
"labels": map[string]interface{}{
6868
"foo": "bar",
6969
},
7070
},
7171
"spec": map[string]interface{}{
7272
"host": "www.example.com",
73-
"to": map[string]string{
73+
"to": map[string]interface{}{
7474
"kind": "Service",
7575
"name": "frontend",
7676
},
@@ -112,7 +112,7 @@ func TestSelect(t *testing.T) {
112112
))
113113
}
114114

115-
func run_TestSelect(given map[string]interface{}, givenSelect []string, expect map[string]interface{}) func(*testing.T) {
115+
func run_TestSelect(given map[string]interface{}, givenSelect []FieldPath, expect map[string]interface{}) func(*testing.T) {
116116
return func(t *testing.T) {
117117
t.Helper()
118118
givenPtr := unstructured.Unstructured{Object: given}
@@ -130,10 +130,9 @@ func TestSelectMissingSelectedField(t *testing.T) {
130130
},
131131
}
132132

133-
fieldsToSelect := []string{
134-
"kind", // required for unstructured unmarshal
135-
"missing",
136-
"/missing",
133+
fieldsToSelect := []FieldPath{
134+
{"kind"}, // required for unstructured unmarshal
135+
{"missing"},
137136
}
138137

139138
err := Select(fieldsToSelect, resource)
@@ -156,7 +155,7 @@ func TestRedactSecret(t *testing.T) {
156155
"metadata": map[string]interface{}{
157156
"name": "example",
158157
"namespace": "example",
159-
"annotations": map[string]string{
158+
"annotations": map[string]interface{}{
160159
"kubectl.kubernetes.io/last-applied-configuration": "secret",
161160
},
162161
"managedFields": nil,
@@ -169,10 +168,10 @@ func TestRedactSecret(t *testing.T) {
169168
},
170169
}
171170

172-
fieldsToRedact := []string{
173-
"metadata.managedFields",
174-
"/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration",
175-
"/data/tls.key",
171+
fieldsToRedact := []FieldPath{
172+
{"metadata", "managedFields"},
173+
{"metadata", "annotations", "kubectl.kubernetes.io/last-applied-configuration"},
174+
{"data", "tls.key"},
176175
}
177176

178177
err := Redact(fieldsToRedact, resource)
@@ -213,8 +212,8 @@ func TestRedactPod(t *testing.T) {
213212
},
214213
}
215214

216-
fieldsToRedact := []string{
217-
"metadata.managedFields",
215+
fieldsToRedact := []FieldPath{
216+
{"metadata", "managedFields"},
218217
}
219218

220219
err := Redact(fieldsToRedact, resource)
@@ -244,9 +243,8 @@ func TestRedactMissingField(t *testing.T) {
244243
},
245244
}
246245

247-
fieldsToRedact := []string{
248-
"missing",
249-
"/missing",
246+
fieldsToRedact := []FieldPath{
247+
{"missing"},
250248
}
251249

252250
err := Redact(fieldsToRedact, resource)

0 commit comments

Comments
 (0)