Skip to content

Commit 339f991

Browse files
CyberArk(client): extract cluster UID from data readings
- Added `extractClusterUIDFromReading` to derive the cluster UID from `ark/namespaces` data readings. - Updated `ConvertDataReadingsToCyberarkSnapshot` to include the cluster UID in the snapshot. - Modified tests to validate cluster UID extraction logic. - Updated example test data to include `ark/namespaces` data gatherer. - Removed `pkg/clusteruid` package as its functionality is now integrated into the client logic. Signed-off-by: Richard Wall <[email protected]>
1 parent 7686607 commit 339f991

File tree

9 files changed

+79
-91
lines changed

9 files changed

+79
-91
lines changed

pkg/client/client_cyberark.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"net/http"
78

@@ -55,9 +56,6 @@ func (o *CyberArkClient) PostDataReadingsWithOptions(ctx context.Context, readin
5556
if err != nil {
5657
return fmt.Errorf("while converting data readings: %s", err)
5758
}
58-
// Temporary hard coded cluster ID.
59-
// TODO(wallrj): The clusterID will eventually be extracted from the supplied readings.
60-
snapshot.ClusterID = "success-cluster-id"
6159

6260
err = datauploadClient.PutSnapshot(ctx, snapshot)
6361
if err != nil {
@@ -85,6 +83,25 @@ var gathererNameToResourceDataKeyMap = map[string]string{
8583
"ark/pods": "pods",
8684
}
8785

86+
// extractClusterUIDFromReading converts the opaque data from a DynamicData
87+
// reading to Unstructured Namespace resources, and finds the UID of the
88+
// `kube-system` namespace.
89+
// This UID can be used as a unique identifier for the Kubernetes cluster.
90+
// - https://venafi.slack.com/archives/C04SQR5DAD7/p1747825325264979
91+
// - https://github.com/kubernetes/kubernetes/issues/77487#issuecomment-489786023
92+
func extractClusterUIDFromReading(reading *api.DataReading) (string, error) {
93+
resources, err := extractResourceListFromReading(reading)
94+
if err != nil {
95+
return "", err
96+
}
97+
for _, resource := range resources {
98+
if resource.GetName() == "kube-system" {
99+
return string(resource.GetUID()), nil
100+
}
101+
}
102+
return "", fmt.Errorf("kube-system namespace UID not found in data reading: %v", reading)
103+
}
104+
88105
// extractServerVersionFromReading converts the opaque data from a DiscoveryData
89106
// data reding to allow access to the Kubernetes version fields within.
90107
func extractServerVersionFromReading(reading *api.DataReading) (string, error) {
@@ -124,6 +141,7 @@ func ConvertDataReadingsToCyberarkSnapshot(
124141
readings []*api.DataReading,
125142
) (s dataupload.Snapshot, _ error) {
126143
k8sVersion := ""
144+
clusterID := ""
127145
resourceData := resourceData{}
128146
for _, reading := range readings {
129147
if reading.DataGatherer == "ark/discovery" {
@@ -133,6 +151,13 @@ func ConvertDataReadingsToCyberarkSnapshot(
133151
return s, fmt.Errorf("while extracting server version from data-reading: %s", err)
134152
}
135153
}
154+
if reading.DataGatherer == "ark/namespaces" {
155+
var err error
156+
clusterID, err = extractClusterUIDFromReading(reading)
157+
if err != nil {
158+
return s, fmt.Errorf("while extracting cluster UID from data-reading: %s", err)
159+
}
160+
}
136161
if key, found := gathererNameToResourceDataKeyMap[reading.DataGatherer]; found {
137162
resources, err := extractResourceListFromReading(reading)
138163
if err != nil {
@@ -141,10 +166,13 @@ func ConvertDataReadingsToCyberarkSnapshot(
141166
resourceData[key] = append(resourceData[key], resources...)
142167
}
143168
}
144-
169+
if clusterID == "" {
170+
return s, errors.New("failed to compute a clusterID from the data-readings")
171+
}
145172
return dataupload.Snapshot{
146173
AgentVersion: version.PreflightVersion,
147174
K8SVersion: k8sVersion,
175+
ClusterID: clusterID,
148176
Secrets: resourceData["secrets"],
149177
ServiceAccounts: resourceData["serviceaccounts"],
150178
Roles: resourceData["roles"],

pkg/client/client_cyberark_test.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"github.com/jetstack/venafi-connection-lib/http_client"
1111
"github.com/stretchr/testify/assert"
1212
"github.com/stretchr/testify/require"
13+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14+
"k8s.io/apimachinery/pkg/types"
1315
"k8s.io/client-go/transport"
1416
"k8s.io/klog/v2"
1517
"k8s.io/klog/v2/ktesting"
@@ -24,6 +26,40 @@ import (
2426
_ "k8s.io/klog/v2/ktesting/init"
2527
)
2628

29+
func genNamespace(name string) *unstructured.Unstructured {
30+
o := &unstructured.Unstructured{}
31+
o.SetAPIVersion("")
32+
o.SetKind("Namespace")
33+
o.SetName(name)
34+
return o
35+
}
36+
37+
func genArkNamespacesDataReading(clusterID types.UID) *api.DataReading {
38+
kubeSystemNamespace := genNamespace("kube-system")
39+
kubeSystemNamespace.SetUID(clusterID)
40+
return &api.DataReading{
41+
ClusterID: "ignored-tlspk-cluster-id",
42+
DataGatherer: "ark/namespaces",
43+
Data: &api.DynamicData{
44+
Items: []*api.GatheredResource{
45+
{
46+
Resource: kubeSystemNamespace,
47+
},
48+
{
49+
Resource: genNamespace("kube-public"),
50+
},
51+
{
52+
Resource: genNamespace("venafi"),
53+
},
54+
{
55+
Resource: genNamespace("cert-manager"),
56+
},
57+
},
58+
},
59+
SchemaVersion: "v1",
60+
}
61+
}
62+
2763
// TestCyberArkClient_PostDataReadingsWithOptions_MockAPI demonstrates that the
2864
// dataupload code works with the mock CyberArk APIs.
2965
// The environment variables are chosen to match those expected by the mock
@@ -41,7 +77,9 @@ func TestCyberArkClient_PostDataReadingsWithOptions_MockAPI(t *testing.T) {
4177
c, err := client.NewCyberArk(httpClient)
4278
require.NoError(t, err)
4379

44-
var readings []*api.DataReading
80+
readings := []*api.DataReading{
81+
genArkNamespacesDataReading("success-cluster-id"),
82+
}
4583
err = c.PostDataReadingsWithOptions(ctx, readings, client.Options{})
4684
require.NoError(t, err)
4785
})

pkg/client/testdata/example-1/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ go run . agent \
1414
--one-shot \
1515
--agent-config-file pkg/client/testdata/example-1/agent.yaml \
1616
--output-path pkg/client/testdata/example-1/datareadings.json
17-
gzip pkg/internal/cyberark/dataupload/testdata/example-1/datareadings.json
17+
gzip pkg/client/testdata/example-1/datareadings.json
1818
```
1919

2020

pkg/client/testdata/example-1/agent.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ data-gatherers:
44
# gather k8s apiserver version information
55
- kind: k8s-discovery
66
name: ark/discovery
7+
- kind: k8s-dynamic
8+
name: ark/namespaces
9+
config:
10+
resource-type:
11+
version: v1
12+
resource: namespaces
713
- kind: k8s-dynamic
814
name: ark/secrets
915
config:
Binary file not shown.
-107 KB
Binary file not shown.

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/internal/cyberark/dataupload/mock.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func (mds *mockDataUploadServer) handleSnapshotLinks(w http.ResponseWriter, r *h
123123
}
124124

125125
if req.ClusterID != successClusterID {
126-
http.Error(w, "post body contains cluster ID", http.StatusInternalServerError)
126+
http.Error(w, "post body does not contain cluster ID", http.StatusInternalServerError)
127127
return
128128
}
129129

0 commit comments

Comments
 (0)