Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/monitor/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ func NewMonitor(log *logrus.Entry, restConfig *rest.Config, oc *api.OpenShiftClu
mon.emitPrometheusAlerts, // at the end for now because it's the slowest/least reliable
mon.emitCWPStatus,
mon.emitClusterAuthenticationType,
mon.emitNetworkMTU,
}

return mon, nil
Expand Down
36 changes: 36 additions & 0 deletions pkg/monitor/cluster/networkmtu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cluster

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
"context"
"strconv"

"github.com/sirupsen/logrus"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// emitNetworkMTU collects and emits metrics related to cluster network MTU configuration
func (mon *Monitor) emitNetworkMTU(ctx context.Context) error {
networkConfig, err := mon.configcli.ConfigV1().Networks().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
return err
}

mtuString := strconv.Itoa(networkConfig.Status.ClusterNetworkMTU)

mon.emitGauge("network.mtu", 1, map[string]string{
"mtu": mtuString,
"network_type": networkConfig.Spec.NetworkType,
})

if mon.hourlyRun {
mon.log.WithFields(logrus.Fields{
"mtu": mtuString,
"network_type": networkConfig.Spec.NetworkType,
}).Info("network MTU configuration")
}
return nil
}
157 changes: 157 additions & 0 deletions pkg/monitor/cluster/networkmtu_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package cluster

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
"context"
"strings"
"testing"

"go.uber.org/mock/gomock"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

configv1 "github.com/openshift/api/config/v1"
configfake "github.com/openshift/client-go/config/clientset/versioned/fake"

"github.com/Azure/ARO-RP/pkg/api"
mock_metrics "github.com/Azure/ARO-RP/pkg/util/mocks/metrics"
testlog "github.com/Azure/ARO-RP/test/util/log"
)

func TestEmitNetworkMTU(t *testing.T) {
ctx := context.Background()

tests := []struct {
name string
oc *api.OpenShiftCluster
networkConfig *configv1.Network
expectedMetric metricExpectation
}{
{
name: "MTU 1500 cluster with OpenShiftSDN",
oc: &api.OpenShiftCluster{
Properties: api.OpenShiftClusterProperties{
NetworkProfile: api.NetworkProfile{
MTUSize: api.MTU1500,
},
},
},
networkConfig: &configv1.Network{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster",
},
Spec: configv1.NetworkSpec{
NetworkType: "OpenShiftSDN",
},
Status: configv1.NetworkStatus{
ClusterNetworkMTU: 1500,
},
},
expectedMetric: metricExpectation{
name: "network.mtu",
value: 1,
labels: map[string]string{
"mtu": "1500",
"network_type": "OpenShiftSDN",
},
},
},
{
name: "MTU 1400 cluster with OVNKubernetes",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me what value this second test adds after the first one. Do we expect OVN to have some difference to the outcome?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second test validates different network types emit different MTU values (1400 vs 1500) and correct network_type labels, ensuring our monitoring works across both OpenShiftSDN and OVNKubernetes network implementations.

oc: &api.OpenShiftCluster{
Properties: api.OpenShiftClusterProperties{
NetworkProfile: api.NetworkProfile{
MTUSize: api.MTU1500,
},
},
},
networkConfig: &configv1.Network{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster",
},
Spec: configv1.NetworkSpec{
NetworkType: "OVNKubernetes",
},
Status: configv1.NetworkStatus{
ClusterNetworkMTU: 1400,
},
},
expectedMetric: metricExpectation{
name: "network.mtu",
value: 1,
labels: map[string]string{
"mtu": "1400",
"network_type": "OVNKubernetes",
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
controller := gomock.NewController(t)
m := mock_metrics.NewMockEmitter(controller)
_, log := testlog.New()

configcli := configfake.NewSimpleClientset(tt.networkConfig)

mon := &Monitor{
oc: tt.oc,
configcli: configcli,
m: m,
log: log,
}

m.EXPECT().EmitGauge(tt.expectedMetric.name, tt.expectedMetric.value, tt.expectedMetric.labels)

err := mon.emitNetworkMTU(ctx)
if err != nil {
t.Errorf("emitNetworkMTU() error = %v", err)
}
})
}
}

func TestEmitNetworkMTUError(t *testing.T) {
ctx := context.Background()

controller := gomock.NewController(t)
m := mock_metrics.NewMockEmitter(controller)
_, log := testlog.New()

oc := &api.OpenShiftCluster{
Properties: api.OpenShiftClusterProperties{
NetworkProfile: api.NetworkProfile{
MTUSize: api.MTU1500,
},
},
}

configcli := configfake.NewSimpleClientset()

mon := &Monitor{
oc: oc,
configcli: configcli,
m: m,
log: log,
}

err := mon.emitNetworkMTU(ctx)
if err == nil {
t.Error("expected error when network config is not found, got nil")
}

// Assert that it's a "not found" error
if err != nil && !strings.Contains(err.Error(), "not found") {
t.Errorf("expected 'not found' error, got: %v", err)
}
}

// metricExpectation represents an expected metric emission
type metricExpectation struct {
name string
value int64
labels map[string]string
}
Loading