Skip to content

Commit

Permalink
fix metrics aggregate controller
Browse files Browse the repository at this point in the history
  • Loading branch information
zreigz committed Oct 18, 2024
1 parent a3e941a commit 4be0288
Show file tree
Hide file tree
Showing 6 changed files with 653 additions and 23 deletions.
9 changes: 8 additions & 1 deletion .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@ packages:
Client:
k8s.io/client-go/discovery:
interfaces:
DiscoveryInterface:
DiscoveryInterface:
k8s.io/metrics/pkg/client/clientset/versioned:
interfaces:
Interface:
k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1:
interfaces:
MetricsV1beta1Interface:
NodeMetricsInterface:
20 changes: 13 additions & 7 deletions internal/controller/metricsaggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ func (r *MetricsAggregateReconciler) Reconcile(ctx context.Context, req ctrl.Req

availableResources := make(map[string]corev1.ResourceList)
for _, n := range nodeList.Items {
availableResources[n.Name] = n.Status.Allocatable
// Total number, contains system reserved resources
availableResources[n.Name] = n.Status.Capacity
}

nodeDeploymentNodesMetrics := make([]v1beta1.NodeMetrics, 0)
Expand All @@ -114,12 +115,17 @@ func (r *MetricsAggregateReconciler) Reconcile(ctx context.Context, req ctrl.Req

// save metrics
metrics.Status.Nodes = len(nodeList.Items)
var cpuAvailableMillicores, cpuTotalMillicores, memoryAvailableBytes, memoryTotalBytes int64
for _, nm := range nodeMetrics {
metrics.Status.CPUAvailableMillicores += nm.CPUAvailableMillicores
metrics.Status.CPUTotalMillicores += nm.CPUTotalMillicores
metrics.Status.MemoryAvailableBytes += nm.MemoryAvailableBytes
metrics.Status.MemoryTotalBytes += nm.MemoryTotalBytes
cpuAvailableMillicores += nm.CPUAvailableMillicores
cpuTotalMillicores += nm.CPUTotalMillicores
memoryAvailableBytes += nm.MemoryAvailableBytes
memoryTotalBytes += nm.MemoryTotalBytes
}
metrics.Status.CPUAvailableMillicores = cpuAvailableMillicores
metrics.Status.CPUTotalMillicores = cpuTotalMillicores
metrics.Status.MemoryAvailableBytes = memoryAvailableBytes
metrics.Status.MemoryTotalBytes = memoryTotalBytes

fraction := float64(metrics.Status.CPUTotalMillicores) / float64(metrics.Status.CPUAvailableMillicores) * 100
metrics.Status.CPUUsedPercentage = int64(fraction)
Expand Down Expand Up @@ -191,8 +197,8 @@ func ConvertNodeMetrics(metrics []v1beta1.NodeMetrics, availableResources map[st
if available, found := resourceMetricsInfo.Available[corev1.ResourceMemory]; found {
quantityM := resourceMetricsInfo.Metrics[corev1.ResourceMemory]
// memory in bytes
nodeMetric.MemoryTotalBytes = quantityM.Value() / (1024 * 1024)
nodeMetric.MemoryAvailableBytes = available.Value() / (1024 * 1024)
nodeMetric.MemoryTotalBytes = quantityM.Value() // in Bytes
nodeMetric.MemoryAvailableBytes = available.Value() // in Bytes
}
nodeMetrics = append(nodeMetrics, nodeMetric)
}
Expand Down
68 changes: 53 additions & 15 deletions internal/controller/metricsaggregate_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/pluralsh/deployment-operator/api/v1alpha1"
"github.com/pluralsh/deployment-operator/pkg/test/mocks"
"github.com/stretchr/testify/mock"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -20,7 +21,6 @@ import (
var _ = Describe("MetricsAggregate Controller", Ordered, func() {
Context("When reconciling a resource", func() {
const (
nodeMetricsName = "node-metrics"
nodeName = "node"
metricsAggregateName = "global"
namespace = "default"
Expand All @@ -39,28 +39,35 @@ var _ = Describe("MetricsAggregate Controller", Ordered, func() {
},
}

nodeMetrics := types.NamespacedName{Name: nodeMetricsName, Namespace: namespace}
nodeMetrics := types.NamespacedName{Name: nodeName, Namespace: namespace}
node := types.NamespacedName{Name: nodeName, Namespace: namespace}
metricsAggregate := types.NamespacedName{Name: metricsAggregateName, Namespace: namespace}

defaultNodeMetrics := v1beta1.NodeMetrics{
ObjectMeta: metav1.ObjectMeta{
Name: nodeName,
Namespace: namespace,
},
Timestamp: metav1.Time{},
Window: metav1.Duration{},
Usage: map[corev1.ResourceName]resource.Quantity{
"cpu": resource.MustParse("100m"),
"memory": resource.MustParse("100Mi"),
},
}
defaultNodeMetricsList := &v1beta1.NodeMetricsList{
Items: []v1beta1.NodeMetrics{
defaultNodeMetrics,
},
}

nm := &v1beta1.NodeMetrics{}
n := &corev1.Node{}
BeforeAll(func() {
By("Creating node metrics")
err := kClient.Get(ctx, nodeMetrics, nm)
if err != nil && errors.IsNotFound(err) {
Expect(kClient.Create(ctx, &v1beta1.NodeMetrics{
ObjectMeta: metav1.ObjectMeta{
Name: nodeMetricsName,
Namespace: namespace,
},
Timestamp: metav1.Time{},
Window: metav1.Duration{},
Usage: map[corev1.ResourceName]resource.Quantity{
"cpu": resource.MustParse("100m"),
"memory": resource.MustParse("100Mi"),
},
})).To(Succeed())
Expect(kClient.Create(ctx, &defaultNodeMetrics)).To(Succeed())
}

By("Creating Node")
Expand All @@ -74,7 +81,8 @@ var _ = Describe("MetricsAggregate Controller", Ordered, func() {
Spec: corev1.NodeSpec{},
Status: corev1.NodeStatus{
Capacity: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("100m"),
corev1.ResourceCPU: resource.MustParse("1"),
corev1.ResourceMemory: resource.MustParse("1Gi"),
},
},
}
Expand Down Expand Up @@ -104,5 +112,35 @@ var _ = Describe("MetricsAggregate Controller", Ordered, func() {
metrics := &v1alpha1.MetricsAggregate{}
Expect(kClient.Get(ctx, metricsAggregate, metrics)).NotTo(HaveOccurred())
})

It("should create global metrics aggregate", func() {
metricsClient := mocks.NewInterfaceMock(mocks.TestingT)
metricsV1beta1 := mocks.NewMetricsV1beta1InterfaceMock(mocks.TestingT)
nodeMetricses := mocks.NewNodeMetricsInterfaceMock(mocks.TestingT)
metricsClient.On("MetricsV1beta1").Return(metricsV1beta1)
metricsV1beta1.On("NodeMetricses").Return(nodeMetricses)
nodeMetricses.On("List", mock.Anything, mock.Anything).Return(defaultNodeMetricsList, nil)

discoveryClient := mocks.NewDiscoveryInterfaceMock(mocks.TestingT)
discoveryClient.On("ServerGroups").Return(apiGroups, nil)

r := MetricsAggregateReconciler{
Client: kClient,
Scheme: kClient.Scheme(),
DiscoveryClient: discoveryClient,
MetricsClient: metricsClient,
}
_, err := r.Reconcile(ctx, reconcile.Request{NamespacedName: metricsAggregate})
Expect(err).NotTo(HaveOccurred())
metrics := &v1alpha1.MetricsAggregate{}
Expect(kClient.Get(ctx, metricsAggregate, metrics)).NotTo(HaveOccurred())
Expect(metrics.Status.Nodes).Should(Equal(1))
Expect(metrics.Status.CPUAvailableMillicores).Should(Equal(int64(1000)))
Expect(metrics.Status.CPUTotalMillicores).Should(Equal(int64(100)))
Expect(metrics.Status.CPUUsedPercentage).Should(Equal(int64(10)))
Expect(metrics.Status.MemoryAvailableBytes).Should(Equal(int64(1073741824)))
Expect(metrics.Status.MemoryTotalBytes).Should(Equal(int64(104857600)))
Expect(metrics.Status.MemoryUsedPercentage).Should(Equal(int64(9)))
})
})
})
180 changes: 180 additions & 0 deletions pkg/test/mocks/Interface_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4be0288

Please sign in to comment.