Skip to content

Commit 7d79032

Browse files
refactor(client): simplify CyberArk snapshot conversion logic
- Refactored `ConvertDataReadingsToCyberarkSnapshot` to use a `dataupload.Snapshot` pointer for direct population. - Replaced `gathererNameToResourceDataKeyMap` with a switch-case for better readability and maintainability. - Introduced `expectedGathererNames` and validation for missing or unhandled data gatherers. - Updated `extractServerVersionFromReading` and `extractResourceListFromReading` to use output parameters. - Adjusted tests to align with the new `ConvertDataReadingsToCyberarkSnapshot` signature. - Updated test data to reflect changes in snapshot structure.
1 parent d20722c commit 7d79032

File tree

3 files changed

+81
-65
lines changed

3 files changed

+81
-65
lines changed

pkg/client/client_cyberark.go

Lines changed: 78 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import (
66
"net/http"
77

88
"k8s.io/apimachinery/pkg/runtime"
9+
"k8s.io/apimachinery/pkg/util/sets"
910

1011
"github.com/jetstack/preflight/api"
1112
"github.com/jetstack/preflight/pkg/internal/cyberark"
1213
"github.com/jetstack/preflight/pkg/internal/cyberark/dataupload"
13-
"github.com/jetstack/preflight/pkg/version"
1414
)
1515

1616
// CyberArkClient is a client for publishing data readings to CyberArk's discoverycontext API.
@@ -50,9 +50,8 @@ func (o *CyberArkClient) PostDataReadingsWithOptions(ctx context.Context, readin
5050
if err != nil {
5151
return fmt.Errorf("while initializing data upload client: %s", err)
5252
}
53-
54-
snapshot, err := ConvertDataReadingsToCyberarkSnapshot(readings)
55-
if err != nil {
53+
var snapshot dataupload.Snapshot
54+
if err := ConvertDataReadingsToCyberarkSnapshot(readings, &snapshot); err != nil {
5655
return fmt.Errorf("while converting data readings: %s", err)
5756
}
5857
// Temporary hard coded cluster ID.
@@ -66,47 +65,29 @@ func (o *CyberArkClient) PostDataReadingsWithOptions(ctx context.Context, readin
6665
return nil
6766
}
6867

69-
type resourceData map[string][]runtime.Object
70-
71-
// The names of Datagatherers which have the data to populate the Cyberark
72-
// Snapshot mapped to the key in the Cyberark snapshot.
73-
var gathererNameToResourceDataKeyMap = map[string]string{
74-
"ark/secrets": "secrets",
75-
"ark/serviceaccounts": "serviceaccounts",
76-
"ark/roles": "roles",
77-
"ark/clusterroles": "clusterroles",
78-
"ark/rolebindings": "rolebindings",
79-
"ark/clusterrolebindings": "clusterrolebindings",
80-
"ark/jobs": "jobs",
81-
"ark/cronjobs": "cronjobs",
82-
"ark/deployments": "deployments",
83-
"ark/statefulsets": "statefulsets",
84-
"ark/daemonsets": "daemonsets",
85-
"ark/pods": "pods",
86-
}
87-
8868
// extractServerVersionFromReading converts the opaque data from a DiscoveryData
8969
// data reading to allow access to the Kubernetes version fields within.
90-
func extractServerVersionFromReading(reading *api.DataReading) (string, error) {
70+
func extractServerVersionFromReading(reading *api.DataReading, target *string) error {
9171
data, ok := reading.Data.(*api.DiscoveryData)
9272
if !ok {
93-
return "", fmt.Errorf(
73+
return fmt.Errorf(
9474
"programmer mistake: the DataReading must have data type *api.DiscoveryData. "+
9575
"This DataReading (%s) has data type %T", reading.DataGatherer, reading.Data)
9676
}
9777
if data.ServerVersion == nil {
98-
return "unknown", nil
78+
return nil
9979
}
100-
return data.ServerVersion.GitVersion, nil
80+
*target = data.ServerVersion.GitVersion
81+
return nil
10182
}
10283

10384
// extractResourceListFromReading converts the opaque data from a DynamicData
10485
// data reading to runtime.Object resources, to allow access to the metadata and
10586
// other kubernetes API fields.
106-
func extractResourceListFromReading(reading *api.DataReading) ([]runtime.Object, error) {
87+
func extractResourceListFromReading(reading *api.DataReading, target *[]runtime.Object) error {
10788
data, ok := reading.Data.(*api.DynamicData)
10889
if !ok {
109-
return nil, fmt.Errorf(
90+
return fmt.Errorf(
11091
"programmer mistake: the DataReading must have data type *api.DynamicData. "+
11192
"This DataReading (%s) has data type %T", reading.DataGatherer, reading.Data)
11293
}
@@ -115,12 +96,28 @@ func extractResourceListFromReading(reading *api.DataReading) ([]runtime.Object,
11596
if resource, ok := item.Resource.(runtime.Object); ok {
11697
resources[i] = resource
11798
} else {
118-
return nil, fmt.Errorf(
99+
return fmt.Errorf(
119100
"programmer mistake: the DynamicData items must have Resource type runtime.Object. "+
120101
"This item (%d) has Resource type %T", i, item.Resource)
121102
}
122103
}
123-
return resources, nil
104+
*target = resources
105+
return nil
106+
}
107+
108+
var expectedGathererNames = []string{
109+
"ark/secrets",
110+
"ark/serviceaccounts",
111+
"ark/roles",
112+
"ark/clusterroles",
113+
"ark/rolebindings",
114+
"ark/clusterrolebindings",
115+
"ark/jobs",
116+
"ark/cronjobs",
117+
"ark/deployments",
118+
"ark/statefulsets",
119+
"ark/daemonsets",
120+
"ark/pods",
124121
}
125122

126123
// ConvertDataReadingsToCyberarkSnapshot converts a list of DataReadings to a CyberArk Snapshot.
@@ -129,40 +126,57 @@ func extractResourceListFromReading(reading *api.DataReading) ([]runtime.Object,
129126
// If any required data is missing or cannot be converted, an error is returned.
130127
func ConvertDataReadingsToCyberarkSnapshot(
131128
readings []*api.DataReading,
132-
) (s dataupload.Snapshot, _ error) {
133-
k8sVersion := ""
134-
resourceData := resourceData{}
135-
for _, reading := range readings {
136-
if reading.DataGatherer == "ark/discovery" {
137-
var err error
138-
k8sVersion, err = extractServerVersionFromReading(reading)
139-
if err != nil {
140-
return s, fmt.Errorf("while extracting server version from data-reading: %s", err)
141-
}
129+
snapshot *dataupload.Snapshot,
130+
) error {
131+
allDataGathererNames := make([]string, len(readings))
132+
unhandledDataGatherers := sets.New[string]()
133+
expectedDataGatherers := sets.New[string](expectedGathererNames...)
134+
for i, reading := range readings {
135+
dataGathererName := reading.DataGatherer
136+
allDataGathererNames[i] = dataGathererName
137+
var err error
138+
switch reading.DataGatherer {
139+
case "ark/discovery":
140+
err = extractServerVersionFromReading(reading, &snapshot.K8SVersion)
141+
case "ark/secrets":
142+
err = extractResourceListFromReading(reading, &snapshot.Secrets)
143+
case "ark/serviceaccounts":
144+
err = extractResourceListFromReading(reading, &snapshot.ServiceAccounts)
145+
case "ark/roles":
146+
err = extractResourceListFromReading(reading, &snapshot.Roles)
147+
case "ark/clusterroles":
148+
err = extractResourceListFromReading(reading, &snapshot.ClusterRoles)
149+
case "ark/rolebindings":
150+
err = extractResourceListFromReading(reading, &snapshot.RoleBindings)
151+
case "ark/clusterrolebindings":
152+
err = extractResourceListFromReading(reading, &snapshot.ClusterRoleBindings)
153+
case "ark/jobs":
154+
err = extractResourceListFromReading(reading, &snapshot.Jobs)
155+
case "ark/cronjobs":
156+
err = extractResourceListFromReading(reading, &snapshot.CronJobs)
157+
case "ark/deployments":
158+
err = extractResourceListFromReading(reading, &snapshot.Deployments)
159+
case "ark/statefulsets":
160+
err = extractResourceListFromReading(reading, &snapshot.Statefulsets)
161+
case "ark/daemonsets":
162+
err = extractResourceListFromReading(reading, &snapshot.Daemonsets)
163+
case "ark/pods":
164+
err = extractResourceListFromReading(reading, &snapshot.Pods)
165+
default:
166+
unhandledDataGatherers.Insert(dataGathererName)
142167
}
143-
if key, found := gathererNameToResourceDataKeyMap[reading.DataGatherer]; found {
144-
resources, err := extractResourceListFromReading(reading)
145-
if err != nil {
146-
return s, fmt.Errorf("while extracting resource list from data-reading: %s", err)
147-
}
148-
resourceData[key] = append(resourceData[key], resources...)
168+
if err != nil {
169+
return fmt.Errorf("while extracting data reading %s: %s", dataGathererName, err)
149170
}
150171
}
151-
152-
return dataupload.Snapshot{
153-
AgentVersion: version.PreflightVersion,
154-
K8SVersion: k8sVersion,
155-
Secrets: resourceData["secrets"],
156-
ServiceAccounts: resourceData["serviceaccounts"],
157-
Roles: resourceData["roles"],
158-
ClusterRoles: resourceData["clusterroles"],
159-
RoleBindings: resourceData["rolebindings"],
160-
ClusterRoleBindings: resourceData["clusterrolebindings"],
161-
Jobs: resourceData["jobs"],
162-
CronJobs: resourceData["cronjobs"],
163-
Deployments: resourceData["deployments"],
164-
Statefulsets: resourceData["statefulsets"],
165-
Daemonsets: resourceData["daemonsets"],
166-
Pods: resourceData["pods"],
167-
}, nil
172+
allDataGatherers := sets.New[string](allDataGathererNames...)
173+
missingDataGatherers := expectedDataGatherers.Difference(allDataGatherers)
174+
if missingDataGatherers.Len() > 0 || unhandledDataGatherers.Len() > 0 {
175+
return fmt.Errorf(
176+
"Unexpected data gatherers. missing: %v, unhandled: %v",
177+
sets.List(missingDataGatherers),
178+
sets.List(unhandledDataGatherers),
179+
)
180+
}
181+
return nil
168182
}

pkg/client/client_cyberark_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/jetstack/preflight/api"
1818
"github.com/jetstack/preflight/pkg/client"
1919
"github.com/jetstack/preflight/pkg/internal/cyberark"
20+
"github.com/jetstack/preflight/pkg/internal/cyberark/dataupload"
2021
"github.com/jetstack/preflight/pkg/internal/cyberark/servicediscovery"
2122
"github.com/jetstack/preflight/pkg/testutil"
2223
"github.com/jetstack/preflight/pkg/version"
@@ -78,7 +79,8 @@ func TestCyberArkClient_PostDataReadingsWithOptions_RealAPI(t *testing.T) {
7879

7980
func TestConvertDataReadingsToCyberarkSnapshot(t *testing.T) {
8081
dataReadings := testutil.ParseDataReadings(t, testutil.ReadGZIP(t, "testdata/example-1/datareadings.json.gz"))
81-
snapshot, err := client.ConvertDataReadingsToCyberarkSnapshot(dataReadings)
82+
var snapshot dataupload.Snapshot
83+
err := client.ConvertDataReadingsToCyberarkSnapshot(dataReadings, &snapshot)
8284
require.NoError(t, err)
8385

8486
actualSnapshotBytes, err := json.MarshalIndent(snapshot, "", " ")
-9 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)