Skip to content

Commit

Permalink
feat: Add deploymentID to telemetry object collector (#1597)
Browse files Browse the repository at this point in the history
* feat: add deploymentID to telemetry object collector
  • Loading branch information
salonichf5 authored Feb 22, 2024
1 parent f30d8ac commit a66255b
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 8 deletions.
53 changes: 45 additions & 8 deletions internal/mode/static/telemetry/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ type ProjectMetadata struct {
type Data struct {
ProjectMetadata ProjectMetadata
ClusterID string
ImageSource string
Arch string
DeploymentID string
ImageSource string
NGFResourceCounts NGFResourceCounts
NodeCount int
NGFReplicaCount int
Expand Down Expand Up @@ -101,11 +102,21 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) {
return Data{}, fmt.Errorf("failed to collect NGF resource counts: %w", err)
}

ngfReplicaCount, err := collectNGFReplicaCount(ctx, c.cfg.K8sClientReader, c.cfg.PodNSName)
replicaSet, err := getPodReplicaSet(ctx, c.cfg.K8sClientReader, c.cfg.PodNSName)
if err != nil {
return Data{}, fmt.Errorf("failed to get replica set for pod %s: %w", c.cfg.PodNSName, err)
}

replicaCount, err := getReplicas(replicaSet)
if err != nil {
return Data{}, fmt.Errorf("failed to collect NGF replica count: %w", err)
}

deploymentID, err := getDeploymentID(replicaSet)
if err != nil {
return Data{}, fmt.Errorf("failed to get NGF deploymentID: %w", err)
}

var clusterID string
if clusterID, err = CollectClusterID(ctx, c.cfg.K8sClientReader); err != nil {
return Data{}, fmt.Errorf("failed to collect clusterID: %w", err)
Expand All @@ -118,10 +129,11 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) {
Name: "NGF",
Version: c.cfg.Version,
},
NGFReplicaCount: ngfReplicaCount,
NGFReplicaCount: replicaCount,
ClusterID: clusterID,
ImageSource: c.cfg.ImageSource,
Arch: runtime.GOARCH,
DeploymentID: deploymentID,
}

return data, nil
Expand Down Expand Up @@ -175,23 +187,27 @@ func collectGraphResourceCount(
return ngfResourceCounts, nil
}

func collectNGFReplicaCount(ctx context.Context, k8sClient client.Reader, podNSName types.NamespacedName) (int, error) {
func getPodReplicaSet(
ctx context.Context,
k8sClient client.Reader,
podNSName types.NamespacedName,
) (*appsv1.ReplicaSet, error) {
var pod v1.Pod
if err := k8sClient.Get(
ctx,
types.NamespacedName{Namespace: podNSName.Namespace, Name: podNSName.Name},
&pod,
); err != nil {
return 0, fmt.Errorf("failed to get NGF Pod: %w", err)
return nil, fmt.Errorf("failed to get NGF Pod: %w", err)
}

podOwnerRefs := pod.GetOwnerReferences()
if len(podOwnerRefs) != 1 {
return 0, fmt.Errorf("expected one owner reference of the NGF Pod, got %d", len(podOwnerRefs))
return nil, fmt.Errorf("expected one owner reference of the NGF Pod, got %d", len(podOwnerRefs))
}

if podOwnerRefs[0].Kind != "ReplicaSet" {
return 0, fmt.Errorf("expected pod owner reference to be ReplicaSet, got %s", podOwnerRefs[0].Kind)
return nil, fmt.Errorf("expected pod owner reference to be ReplicaSet, got %s", podOwnerRefs[0].Kind)
}

var replicaSet appsv1.ReplicaSet
Expand All @@ -200,16 +216,37 @@ func collectNGFReplicaCount(ctx context.Context, k8sClient client.Reader, podNSN
types.NamespacedName{Namespace: podNSName.Namespace, Name: podOwnerRefs[0].Name},
&replicaSet,
); err != nil {
return 0, fmt.Errorf("failed to get NGF Pod's ReplicaSet: %w", err)
return nil, fmt.Errorf("failed to get NGF Pod's ReplicaSet: %w", err)
}

return &replicaSet, nil
}

func getReplicas(replicaSet *appsv1.ReplicaSet) (int, error) {
if replicaSet.Spec.Replicas == nil {
return 0, errors.New("replica set replicas was nil")
}

return int(*replicaSet.Spec.Replicas), nil
}

func getDeploymentID(replicaSet *appsv1.ReplicaSet) (string, error) {
replicaOwnerRefs := replicaSet.GetOwnerReferences()
if len(replicaOwnerRefs) != 1 {
return "", fmt.Errorf("expected one owner reference of the NGF ReplicaSet, got %d", len(replicaOwnerRefs))
}

if replicaOwnerRefs[0].Kind != "Deployment" {
return "", fmt.Errorf("expected replicaSet owner reference to be Deployment, got %s", replicaOwnerRefs[0].Kind)
}

if replicaOwnerRefs[0].UID == "" {
return "", fmt.Errorf("expected replicaSet owner reference to have a UID")
}

return string(replicaOwnerRefs[0].UID), nil
}

// CollectClusterID gets the UID of the kube-system namespace.
func CollectClusterID(ctx context.Context, k8sClient client.Reader) (string, error) {
key := types.NamespacedName{
Expand Down
78 changes: 78 additions & 0 deletions internal/mode/static/telemetry/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ var _ = Describe("Collector", Ordered, func() {
Spec: appsv1.ReplicaSetSpec{
Replicas: &replicas,
},
ObjectMeta: metav1.ObjectMeta{
Name: "replica",
OwnerReferences: []metav1.OwnerReference{
{
Kind: "Deployment",
Name: "Deployment1",
UID: "test-uid-replicaSet",
},
},
},
}

podNSName = types.NamespacedName{
Expand All @@ -126,6 +136,7 @@ var _ = Describe("Collector", Ordered, func() {
ClusterID: string(kubeNamespace.GetUID()),
ImageSource: "local",
Arch: runtime.GOARCH,
DeploymentID: string(ngfReplicaSet.ObjectMeta.OwnerReferences[0].UID),
}

k8sClientReader = &eventsfakes.FakeReader{}
Expand Down Expand Up @@ -547,6 +558,7 @@ var _ = Describe("Collector", Ordered, func() {
{
Kind: "Deployment",
Name: "deployment1",
UID: "replica-uid",
},
},
},
Expand Down Expand Up @@ -588,4 +600,70 @@ var _ = Describe("Collector", Ordered, func() {
})
})
})

Describe("DeploymentID collector", func() {
When("collecting deploymentID", func() {
When("it encounters an error while collecting data", func() {
It("should error if the replicaSet's owner reference is nil", func() {
replicas := int32(1)
k8sClientReader.GetCalls(mergeGetCallsWithBase(createGetCallsFunc(
&appsv1.ReplicaSet{
Spec: appsv1.ReplicaSetSpec{
Replicas: &replicas,
},
},
)))

expectedErr := errors.New("expected one owner reference of the NGF ReplicaSet, got 0")
_, err := dataCollector.Collect(ctx)
Expect(err).To(MatchError(expectedErr))
})

It("should error if the replicaSet's owner reference kind is not deployment", func() {
replicas := int32(1)
k8sClientReader.GetCalls(mergeGetCallsWithBase(createGetCallsFunc(
&appsv1.ReplicaSet{
Spec: appsv1.ReplicaSetSpec{
Replicas: &replicas,
},
ObjectMeta: metav1.ObjectMeta{
OwnerReferences: []metav1.OwnerReference{
{
Name: "replica",
Kind: "ReplicaSet",
},
},
},
},
)))

expectedErr := errors.New("expected replicaSet owner reference to be Deployment, got ReplicaSet")
_, err := dataCollector.Collect(ctx)
Expect(err).To(MatchError(expectedErr))
})
It("should error if the replicaSet's owner reference has empty UID", func() {
replicas := int32(1)
k8sClientReader.GetCalls(mergeGetCallsWithBase(createGetCallsFunc(
&appsv1.ReplicaSet{
Spec: appsv1.ReplicaSetSpec{
Replicas: &replicas,
},
ObjectMeta: metav1.ObjectMeta{
OwnerReferences: []metav1.OwnerReference{
{
Name: "replica",
Kind: "Deployment",
},
},
},
},
)))

expectedErr := errors.New("expected replicaSet owner reference to have a UID")
_, err := dataCollector.Collect(ctx)
Expect(err).To(MatchError(expectedErr))
})
})
})
})
})

0 comments on commit a66255b

Please sign in to comment.