Skip to content

Commit 6dd5dc2

Browse files
CyberArk(client): include cluster ID in discovery data
- Added `ClusterID` field to `DiscoveryData` to store the unique Kubernetes cluster identifier derived from the `kube-system` namespace UID. - Updated `DataGathererDiscovery` to fetch and store the cluster ID during initialization. - Refactored `extractServerVersionFromReading` to `extractClusterIDAndServerVersionFromReading` to handle both cluster ID and server version extraction. - Removed `clusteruid` package as its functionality is now integrated into the `discovery` data gatherer. - Updated unit tests to validate the inclusion of `ClusterID` in snapshots. Signed-off-by: Richard Wall <richard.wall@cyberark.com>
1 parent 47a46c7 commit 6dd5dc2

File tree

7 files changed

+48
-110
lines changed

7 files changed

+48
-110
lines changed

api/datareading.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ type DynamicData struct {
6161
// DiscoveryData is the DataReading.Data returned by the k8s.ConfigDiscovery
6262
// gatherer
6363
type DiscoveryData struct {
64+
// ClusterID is the unique ID of the Kubernetes cluster which this snapshot was taken from.
65+
// This is sourced from the kube-system namespace UID,
66+
// which is assumed to be stable for the lifetime of the cluster.
67+
// - https://github.com/kubernetes/kubernetes/issues/77487#issuecomment-489786023
68+
ClusterID string `json:"cluster_id"`
6469
// ServerVersion is the version information of the k8s apiserver
6570
// See https://godoc.org/k8s.io/apimachinery/pkg/version#Info
6671
ServerVersion *version.Info `json:"server_version"`

pkg/client/client_cyberark.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ func (o *CyberArkClient) PostDataReadingsWithOptions(ctx context.Context, readin
4949
return fmt.Errorf("while converting data readings: %s", err)
5050
}
5151
snapshot.AgentVersion = version.PreflightVersion
52-
// Temporary hard coded cluster ID.
53-
// TODO(wallrj): The clusterID will eventually be extracted from the supplied readings.
54-
snapshot.ClusterID = "success-cluster-id"
5552

5653
cfg, err := o.configLoader()
5754
if err != nil {
@@ -69,9 +66,9 @@ func (o *CyberArkClient) PostDataReadingsWithOptions(ctx context.Context, readin
6966
return nil
7067
}
7168

72-
// extractServerVersionFromReading converts the opaque data from a DiscoveryData
69+
// extractClusterIDAndServerVersionFromReading converts the opaque data from a DiscoveryData
7370
// data reading to allow access to the Kubernetes version fields within.
74-
func extractServerVersionFromReading(reading *api.DataReading, target *string) error {
71+
func extractClusterIDAndServerVersionFromReading(reading *api.DataReading, target *dataupload.Snapshot) error {
7572
if reading == nil {
7673
return fmt.Errorf("programmer mistake: the DataReading must not be nil")
7774
}
@@ -81,10 +78,10 @@ func extractServerVersionFromReading(reading *api.DataReading, target *string) e
8178
"programmer mistake: the DataReading must have data type *api.DiscoveryData. "+
8279
"This DataReading (%s) has data type %T", reading.DataGatherer, reading.Data)
8380
}
84-
if data.ServerVersion == nil {
85-
return nil
81+
target.ClusterID = data.ClusterID
82+
if data.ServerVersion != nil {
83+
target.K8SVersion = data.ServerVersion.GitVersion
8684
}
87-
*target = data.ServerVersion.GitVersion
8885
return nil
8986
}
9087

@@ -116,9 +113,7 @@ func extractResourceListFromReading(reading *api.DataReading, target *[]runtime.
116113
}
117114

118115
var defaultExtractorFunctions = map[string]func(*api.DataReading, *dataupload.Snapshot) error{
119-
"ark/discovery": func(r *api.DataReading, s *dataupload.Snapshot) error {
120-
return extractServerVersionFromReading(r, &s.K8SVersion)
121-
},
116+
"ark/discovery": extractClusterIDAndServerVersionFromReading,
122117
"ark/secrets": func(r *api.DataReading, s *dataupload.Snapshot) error {
123118
return extractResourceListFromReading(r, &s.Secrets)
124119
},

pkg/client/client_cyberark_convertdatareadings_test.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ import (
1818
// TestExtractServerVersionFromReading tests the extractServerVersionFromReading function.
1919
func TestExtractServerVersionFromReading(t *testing.T) {
2020
type testCase struct {
21-
name string
22-
reading *api.DataReading
23-
expectedVersion string
24-
expectError string
21+
name string
22+
reading *api.DataReading
23+
expectedSnapshot dataupload.Snapshot
24+
expectError string
2525
}
2626
tests := []testCase{
2727
{
@@ -50,32 +50,36 @@ func TestExtractServerVersionFromReading(t *testing.T) {
5050
DataGatherer: "ark/discovery",
5151
Data: &api.DiscoveryData{},
5252
},
53-
expectedVersion: "",
53+
expectedSnapshot: dataupload.Snapshot{},
5454
},
5555
{
5656
name: "happy path",
5757
reading: &api.DataReading{
5858
DataGatherer: "ark/discovery",
5959
Data: &api.DiscoveryData{
60+
ClusterID: "success-cluster-id",
6061
ServerVersion: &version.Info{
6162
GitVersion: "v1.21.0",
6263
},
6364
},
6465
},
65-
expectedVersion: "v1.21.0",
66+
expectedSnapshot: dataupload.Snapshot{
67+
ClusterID: "success-cluster-id",
68+
K8SVersion: "v1.21.0",
69+
},
6670
},
6771
}
6872
for _, test := range tests {
6973
t.Run(test.name, func(t *testing.T) {
70-
var k8sVersion string
71-
err := extractServerVersionFromReading(test.reading, &k8sVersion)
74+
var snapshot dataupload.Snapshot
75+
err := extractClusterIDAndServerVersionFromReading(test.reading, &snapshot)
7276
if test.expectError != "" {
7377
assert.EqualError(t, err, test.expectError)
74-
assert.Equal(t, "", k8sVersion)
78+
assert.Equal(t, dataupload.Snapshot{}, snapshot)
7579
return
7680
}
7781
require.NoError(t, err)
78-
assert.Equal(t, test.expectedVersion, k8sVersion)
82+
assert.Equal(t, test.expectedSnapshot, snapshot)
7983
})
8084
}
8185
}
@@ -197,9 +201,7 @@ func TestExtractResourceListFromReading(t *testing.T) {
197201
// TestConvertDataReadings tests the convertDataReadings function.
198202
func TestConvertDataReadings(t *testing.T) {
199203
simpleExtractorFunctions := map[string]func(*api.DataReading, *dataupload.Snapshot) error{
200-
"ark/discovery": func(reading *api.DataReading, snapshot *dataupload.Snapshot) error {
201-
return extractServerVersionFromReading(reading, &snapshot.K8SVersion)
202-
},
204+
"ark/discovery": extractClusterIDAndServerVersionFromReading,
203205
"ark/secrets": func(reading *api.DataReading, snapshot *dataupload.Snapshot) error {
204206
return extractResourceListFromReading(reading, &snapshot.Secrets)
205207
},
@@ -208,6 +210,7 @@ func TestConvertDataReadings(t *testing.T) {
208210
{
209211
DataGatherer: "ark/discovery",
210212
Data: &api.DiscoveryData{
213+
ClusterID: "success-cluster-id",
211214
ServerVersion: &version.Info{
212215
GitVersion: "v1.21.0",
213216
},
@@ -278,6 +281,7 @@ func TestConvertDataReadings(t *testing.T) {
278281
extractorFunctions: simpleExtractorFunctions,
279282
readings: simpleReadings,
280283
expectedSnapshot: dataupload.Snapshot{
284+
ClusterID: "success-cluster-id",
281285
K8SVersion: "v1.21.0",
282286
Secrets: []runtime.Object{
283287
&corev1.Secret{

pkg/client/client_cyberark_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ func fakeReadings() []*api.DataReading {
109109
{
110110
DataGatherer: "ark/discovery",
111111
Data: &api.DiscoveryData{
112+
ClusterID: "success-cluster-id",
112113
ServerVersion: &k8sversion.Info{
113114
GitVersion: "v1.21.0",
114115
},

pkg/clusteruid/clusteruid.go

Lines changed: 0 additions & 45 deletions
This file was deleted.

pkg/clusteruid/clusteruid_test.go

Lines changed: 0 additions & 39 deletions
This file was deleted.

pkg/datagatherer/k8s/discovery.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66

7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
78
"k8s.io/client-go/discovery"
89

910
"github.com/jetstack/preflight/api"
@@ -33,19 +34,34 @@ func (c *ConfigDiscovery) UnmarshalYAML(unmarshal func(interface{}) error) error
3334

3435
// NewDataGatherer constructs a new instance of the generic K8s data-gatherer for the provided
3536
// GroupVersionResource.
37+
// It gets the UID of the 'kube-system' namespace to use as the cluster ID, once at startup.
38+
// The UID is assumed to be stable for the lifetime of the cluster.
39+
// - https://github.com/kubernetes/kubernetes/issues/77487#issuecomment-489786023
3640
func (c *ConfigDiscovery) NewDataGatherer(ctx context.Context) (datagatherer.DataGatherer, error) {
3741
cl, err := NewDiscoveryClient(c.KubeConfigPath)
3842
if err != nil {
3943
return nil, err
4044
}
41-
42-
return &DataGathererDiscovery{cl: cl}, nil
45+
cs, err := NewClientSet(c.KubeConfigPath)
46+
if err != nil {
47+
return nil, fmt.Errorf("while creating new clientset: %s", err)
48+
}
49+
kubesystemNS, err := cs.CoreV1().Namespaces().Get(ctx, "kube-system", metav1.GetOptions{})
50+
if err != nil {
51+
return nil, fmt.Errorf("while getting the kube-system namespace: %s", err)
52+
}
53+
return &DataGathererDiscovery{
54+
cl: cl,
55+
clusterID: string(kubesystemNS.UID),
56+
}, nil
4357
}
4458

4559
// DataGathererDiscovery stores the config for a k8s-discovery datagatherer
4660
type DataGathererDiscovery struct {
4761
// The 'discovery' client used for fetching data.
4862
cl *discovery.DiscoveryClient
63+
// The cluster ID, derived from the UID of the 'kube-system' namespace.
64+
clusterID string
4965
}
5066

5167
func (g *DataGathererDiscovery) Run(ctx context.Context) error {
@@ -65,6 +81,7 @@ func (g *DataGathererDiscovery) Fetch() (interface{}, int, error) {
6581
return nil, -1, fmt.Errorf("failed to get server version: %v", err)
6682
}
6783
response := &api.DiscoveryData{
84+
ClusterID: g.clusterID,
6885
ServerVersion: data,
6986
}
7087
return response, 1, nil

0 commit comments

Comments
 (0)