8000 Add NodeCount to telemetry data (#5147) · nginx/kubernetes-ingress@b4114ba · GitHub
[go: up one dir, main page]

Skip to content

Commit b4114ba

Browse files
authored
Add NodeCount to telemetry data (#5147)
1 parent fdc3770 commit b4114ba

File tree

6 files changed

+206
-10
lines changed

6 files changed

+206
-10
lines changed

deployments/rbac/rbac.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ rules:
5454
- get
5555
- list
5656
- watch
57+
- apiGroups:
58+
- ""
59+
resources:
60+
- nodes
61+
verbs:
62+
- list
5763
- apiGroups:
5864
- ""
5965
resources:

internal/telemetry/cluster.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package telemetry
2+
3+
import (
4+
"context"
5+
6+
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
)
8+
9+
// NodeCount returns the total number of nodes in the cluster.
10+
// It returns an error if the underlying k8s API client errors.
11+
func (c *Collector) NodeCount(ctx context.Context) (int, error) {
12+
nodes, err := c.Config.K8sClientReader.CoreV1().Nodes().List(ctx, metaV1.ListOptions{})
13+
if err != nil {
14+
return 0, err
15+
}
16+
return len(nodes.Items), nil
17+
}

internal/telemetry/cluster_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package telemetry_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/nginxinc/kubernetes-ingress/internal/telemetry"
8+
apiCoreV1 "k8s.io/api/core/v1"
9+
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/runtime"
11+
testClient "k8s.io/client-go/kubernetes/fake"
12+
)
13+
14+
func TestNodeCountInAClusterWithThreeNodes(t *testing.T) {
15+
t.Parallel()
16+
17+
c := newTestCollectorForCluserWithNodes(t, node1, node2, node3)
18+
19+
got, err := c.NodeCount(context.Background())
20+
if err != nil {
21+
t.Fatal(err)
22+
}
23+
want := 3
24+
if want != got {
25+
t.Errorf("want %v, got %v", want, got)
26+
}
27+
}
28+
29+
func TestNodeCountInAClusterWithOneNode(t *testing.T) {
30+
t.Parallel()
31+
32+
c := newTestCollectorForCluserWithNodes(t, node1)
33+
got, err := c.NodeCount(context.Background())
34+
if err != nil {
35+
t.Fatal(err)
36+
}
37+
want := 1
38+
if want != got {
39+
t.Errorf("want %v, got %v", want, got)
40+
}
41+
}
42+
43+
// newTestCollectorForClusterWithNodes returns a telemetry collector configured
44+
// to simulate collecting data on a cluser with provided nodes.
45+
func newTestCollectorForCluserWithNodes(t *testing.T, nodes ...runtime.Object) *telemetry.Collector {
46+
t.Helper()
47+
48+
c, err := telemetry.NewCollector(
49+
telemetry.CollectorConfig{},
50+
)
51+
if err != nil {
52+
t.Fatal(err)
53+
}
54+
c.Config.K8sClientReader = testClient.NewSimpleClientset(nodes...)
55+
return c
56+
}
57+
58+
var (
59+
node1 = &apiCoreV1.Node{
60+
TypeMeta: metaV1.TypeMeta{
61+
Kind: "Node",
62+
APIVersion: "v1",
63+
},
64+
ObjectMeta: metaV1.ObjectMeta{
65+
Name: "test-node-1",
66+
Namespace: "default",
67+
},
68+
Spec: apiCoreV1.NodeSpec{},
69+
}
70+
71+
node2 = &apiCoreV1.Node{
72+
TypeMeta: metaV1.TypeMeta{
73+
Kind: "Node",
74+
APIVersion: "v1",
75+
},
76+
ObjectMeta: metaV1.ObjectMeta{
77+
Name: "test-node-2",
78+
Namespace: "default",
79+
},
80+
Spec: apiCoreV1.NodeSpec{},
81+
}
82+
83+
node3 = &apiCoreV1.Node{
84+
TypeMeta: metaV1.TypeMeta{
85+
Kind: "Node",
86+
APIVersion: "v1",
87+
},
88+
ObjectMeta: metaV1.ObjectMeta{
89+
Name: "test-node-3",
90+
Namespace: "default",
91+
},
92+
Spec: apiCoreV1.NodeSpec{},
93+
}
94+
)

internal/telemetry/collector.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ func (c *Collector) Start(ctx context.Context) {
7979
// It exports data using provided exporter.
8080
func (c *Collector) Collect(ctx context.Context) {
8181
glog.V(3).Info("Collecting telemetry data")
82-
// TODO: Re-add ctx to BuildReport when collecting Node Count.
83-
data, err := c.BuildReport()
82+
data, err := c.BuildReport(ctx)
8483
if err != nil {
8584
glog.Errorf("Error collecting telemetry data: %v", err)
8685
}
@@ -92,13 +91,18 @@ func (c *Collector) Collect(ctx context.Context) {
9291
}
9392

9493
// BuildReport takes context and builds report from gathered telemetry data.
95-
func (c *Collector) BuildReport() (Data, error) {
94+
func (c *Collector) BuildReport(ctx context.Context) (Data, error) {
9695
d := Data{}
9796
var err error
9897

9998
if c.Config.Configurator != nil {
10099
d.NICResourceCounts.VirtualServers, d.NICResourceCounts.VirtualServerRoutes = c.Config.Configurator.GetVirtualServerCounts()
101100
d.NICResourceCounts.TransportServers = c.Config.Configurator.GetTransportServerCounts()
102101
}
102+
nc, err := c.NodeCount(ctx)
103+
if err != nil {
104+
glog.Errorf("Error collecting telemetry data: Nodes: %v", err)
105+
}
106+
d.NodeCount = nc
103107
return d, err
104108
}

internal/telemetry/collector_test.go

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/nginxinc/kubernetes-ingress/internal/telemetry"
1717
conf_v1 "github.com/nginxinc/kubernetes-ingress/pkg/apis/configuration/v1"
1818
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19+
testClient "k8s.io/client-go/kubernetes/fake"
1920
)
2021

2122
func TestCreateNewCollectorWithCustomReportingPeriod(t *testing.T) {
@@ -46,7 +47,8 @@ func TestCreateNewCollectorWithCustomExporter(t *testing.T) {
4647
td := telemetry.Data{}
4748

4849
cfg := telemetry.CollectorConfig{
49-
Configurator: newConfigurator(t),
50+
K8sClientReader: testClient.NewSimpleClientset(),
51+
Configurator: newConfigurator(t),
5052
}
5153

5254
c, err := telemetry.NewCollector(cfg, telemetry.WithExporter(exp))
@@ -62,6 +64,76 @@ func TestCreateNewCollectorWithCustomExporter(t *testing.T) {
6264
}
6365
}
6466

67+
func TestCollectNodeCountInClusterWithOneNode(t *testing.T) {
68+
t.Parallel()
69+
70+
buf := &bytes.Buffer{}
71+
exp := &telemetry.StdoutExporter{Endpoint: buf}
72+
cfg := telemetry.CollectorConfig{
73+
Configurator: newConfigurator(t),
74+
K8sClientReader: testClient.NewSimpleClientset(node1),
75+
}
76+
77+
c, err := telemetry.NewCollector(cfg, telemetry.WithExporter(exp))
78+
if err != nil {
79+
t.Fatal(err)
80+
}
81+
c.Collect(context.Background())
82+
83+
td := telemetry.Data{
84+
ProjectMeta: telemetry.ProjectMeta{
85+
Name: "",
86+
Version: "",
87+
},
88+
NICResourceCounts: telemetry.NICResourceCounts{
89+
VirtualServers: 0,
90+
VirtualServerRoutes: 0,
91+
TransportServers: 0,
92+
},
93+
NodeCount: 1,
94+
}
95+
want := fmt.Sprintf("%+v", td)
96+
got := buf.String()
97+
if !cmp.Equal(want, got) {
98+
t.Error(cmp.Diff(want, got))
99+
}
100+
}
101+
102+
func TestCollectNodeCountInClusterWithThreeNodes(t *testing.T) {
103+
t.Parallel()
104+
105+
buf := &bytes.Buffer{}
106+
exp := &telemetry.StdoutExporter{Endpoint: buf}
107+
cfg := telemetry.CollectorConfig{
108+
Configurator: newConfigurator(t),
109+
K8sClientReader: testClient.NewSimpleClientset(node1, node2, node3),
110+
}
111+
112+
c, err := telemetry.NewCollector(cfg, telemetry.WithExporter(exp))
113+
if err != nil {
114+
t.Fatal(err)
115+
}
116+
c.Collect(context.Background())
117+
118+
td := telemetry.Data{
119+
ProjectMeta: telemetry.ProjectMeta{
120+
Name: "",
121+
Version: "",
122+
},
123+
NICResourceCounts: telemetry.NICResourceCounts{
124+
VirtualServers: 0,
125+
VirtualServerRoutes: 0,
126+
TransportServers: 0,
127+
},
128+
NodeCount: 3,
129+
}
130+
want := fmt.Sprintf("%+v", td)
131+
got := buf.String()
132+
if !cmp.Equal(want, got) {
133+
t.Error(cmp.Diff(want, got))
134+
}
135+
}
136+
65137
func TestCountVirtualServers(t *testing.T) {
66138
t.Parallel()
67139

@@ -171,7 +243,8 @@ func TestCountVirtualServers(t *testing.T) {
171243
configurator := newConfigurator(t)
172244

173245
c, err := telemetry.NewCollector(telemetry.CollectorConfig{
174-
Configurator: configurator,
246+
K8sClientReader: testClient.NewSimpleClientset(),
247+
Configurator: configurator,
175248
})
176249
if err != nil {
177250
t.Fatal(err)
@@ -184,7 +257,7 @@ func TestCountVirtualServers(t *testing.T) {
184257
}
185258
}
186259

187-
gotTraceDataOnAdd, err := c.BuildReport()
260+
gotTraceDataOnAdd, err := c.BuildReport(context.Background())
188261
if err != nil {
189262
t.Fatal(err)
190263
}
@@ -202,7 +275,7 @@ func TestCountVirtualServers(t *testing.T) {
202275
}
203276
}
204277

205-
gotTraceDataOnDelete, err := c.BuildReport()
278+
gotTraceDataOnDelete, err := c.BuildReport(context.Background())
206279
if err != nil {
207280
t.Fatal(err)
208281
}
@@ -342,7 +415,8 @@ func TestCountTransportServers(t *testing.T) {
342415
configurator := newConfigurator(t)
343416

344417
c, err := telemetry.NewCollector(telemetry.CollectorConfig{
345-
Configurator: configurator,
418+
K8sClientReader: testClient.NewSimpleClientset(),
419+
Configurator: configurator,
346420
})
347421
if err != nil {
348422
t.Fatal(err)
@@ -355,7 +429,7 @@ func TestCountTransportServers(t *testing.T) {
355429
}
356430
}
357431

358-
gotTraceDataOnAdd, err := c.BuildReport()
432+
gotTraceDataOnAdd, err := c.BuildReport(context.Background())
359433
if err != nil {
360434
t.Fatal(err)
361435
}
@@ -373,7 +447,7 @@ func TestCountTransportServers(t *testing.T) {
373447
}
374448
}
375449

376-
gotTraceDataOnDelete, err := c.BuildReport()
450+
gotTraceDataOnDelete, err := c.BuildReport(context.Background())
377451
if err != nil {
378452
t.Fatal(err)
379453
}

internal/telemetry/exporter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func (e *StdoutExporter) Export(_ context.Context, data Data) error {
2929
type Data struct {
3030
ProjectMeta ProjectMeta
3131
NICResourceCounts NICResourceCounts
32+
NodeCount int
3233
}
3334

3435
// ProjectMeta holds metadata for the project.

0 commit comments

Comments
 (0)
0