Skip to content

Commit 9d25e21

Browse files
Merge pull request #670 from jetstack/clusteruid
feat: add cluster uid derived from kube-system ns
2 parents e6f1925 + 398cfd4 commit 9d25e21

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

pkg/agent/run.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
"github.com/jetstack/preflight/api"
3434
"github.com/jetstack/preflight/pkg/client"
35+
"github.com/jetstack/preflight/pkg/clusteruid"
3536
"github.com/jetstack/preflight/pkg/datagatherer"
3637
"github.com/jetstack/preflight/pkg/datagatherer/k8s"
3738
"github.com/jetstack/preflight/pkg/kubeconfig"
@@ -78,6 +79,28 @@ func Run(cmd *cobra.Command, args []string) (returnErr error) {
7879
return fmt.Errorf("While evaluating configuration: %v", err)
7980
}
8081

82+
// We need the cluster UID before we progress further so it can be sent along with other data readings
83+
84+
{
85+
restCfg, err := kubeconfig.LoadRESTConfig("")
86+
if err != nil {
87+
return err
88+
}
89+
90+
clientset, err := kubernetes.NewForConfig(restCfg)
91+
if err != nil {
92+
return err
93+
}
94+
95+
ctx, err = clusteruid.GetClusterUID(ctx, clientset)
96+
if err != nil {
97+
return fmt.Errorf("failed to get cluster UID: %v", err)
98+
}
99+
100+
clusterUID := clusteruid.ClusterUIDFromContext(ctx)
101+
log.V(logs.Debug).Info("Retrieved cluster UID", "clusterUID", clusterUID)
102+
}
103+
81104
group, gctx := errgroup.WithContext(ctx)
82105
defer func() {
83106
cancel()

pkg/clusteruid/clusteruid.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package clusteruid
2+
3+
import (
4+
"context"
5+
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
"k8s.io/client-go/kubernetes"
8+
)
9+
10+
// clusterUIDKey is the context key for storing the cluster UID
11+
type clusterUIDKey struct{}
12+
13+
// GetClusterUID retrieves the UID of the kube-system namespace using the given Kubernetes clientset.
14+
// This UID can be used as a unique identifier for the Kubernetes cluster.
15+
// The UID is stored in the given context for later retrieval; use ClusterUIDFromContext to get it.
16+
func GetClusterUID(ctx context.Context, clientset kubernetes.Interface) (context.Context, error) {
17+
namespace, err := clientset.CoreV1().Namespaces().Get(ctx, "kube-system", metav1.GetOptions{})
18+
if err != nil {
19+
return ctx, err
20+
}
21+
22+
ctx = withClusterUID(ctx, string(namespace.ObjectMeta.UID))
23+
return ctx, nil
24+
}
25+
26+
// ClusterUIDFromContext retrieves the cluster UID from the context.
27+
// Panics if the value is not found or if the value is not a string.
28+
func ClusterUIDFromContext(ctx context.Context) string {
29+
value := ctx.Value(clusterUIDKey{})
30+
if value == nil {
31+
panic("cluster UID not found in context")
32+
}
33+
34+
uid, ok := value.(string)
35+
if !ok {
36+
panic("cluster UID in context is not a string")
37+
}
38+
39+
return uid
40+
}
41+
42+
// withClusterUID adds the given cluster UID to the context
43+
func withClusterUID(ctx context.Context, clusterUID string) context.Context {
44+
return context.WithValue(ctx, clusterUIDKey{}, clusterUID)
45+
}

pkg/clusteruid/clusteruid_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package clusteruid
2+
3+
import (
4+
"testing"
5+
6+
corev1 "k8s.io/api/core/v1"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
"k8s.io/apimachinery/pkg/types"
9+
"k8s.io/client-go/kubernetes/fake"
10+
)
11+
12+
func TestGetClusterUID(t *testing.T) {
13+
client := fake.NewSimpleClientset()
14+
15+
mockUID := "12345678-1234-5678-1234-567812345678"
16+
17+
kubeSystemNS := &corev1.Namespace{
18+
ObjectMeta: metav1.ObjectMeta{
19+
Name: "kube-system",
20+
UID: types.UID(mockUID),
21+
},
22+
}
23+
24+
_, err := client.CoreV1().Namespaces().Create(t.Context(), kubeSystemNS, metav1.CreateOptions{})
25+
if err != nil {
26+
t.Fatalf("failed to create kube-system namespace with fake client: %v", err)
27+
}
28+
29+
ctx, err := GetClusterUID(t.Context(), client)
30+
if err != nil {
31+
t.Fatalf("expected no error, got %v", err)
32+
}
33+
34+
uid := ClusterUIDFromContext(ctx)
35+
36+
if uid != mockUID {
37+
t.Fatalf("expected to get uid=%v, but got uid=%v", mockUID, uid)
38+
}
39+
}

0 commit comments

Comments
 (0)