@@ -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.
130127func 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}
0 commit comments