Skip to content

Commit fed9281

Browse files
committed
Add validation webhook to warn about inconsistent scheduling
1 parent 298ca57 commit fed9281

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

api/flowcollector/v1beta2/flowcollector_validation_webhook.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"net"
8+
"reflect"
89
"slices"
910
"strconv"
1011
"strings"
@@ -214,12 +215,29 @@ func validatePortString(s string) (uint16, error) {
214215
}
215216

216217
func (v *validator) validateFLP() {
218+
v.validateScheduling()
217219
v.validateFLPLogTypes()
218220
v.validateFLPFilters()
219221
v.validateFLPAlerts()
220222
v.validateFLPMetricsForAlerts()
221223
}
222224

225+
func (v *validator) validateScheduling() {
226+
if v.fc.DeploymentModel == DeploymentModelDirect {
227+
// In direct mode, agent and FLP scheduling should be consistent, to ensure the 1-1 relation
228+
var agent, flp *SchedulingConfig
229+
if v.fc.Agent.EBPF.Advanced != nil {
230+
agent = v.fc.Agent.EBPF.Advanced.Scheduling
231+
}
232+
if v.fc.Processor.Advanced != nil {
233+
flp = v.fc.Processor.Advanced.Scheduling
234+
}
235+
if !reflect.DeepEqual(agent, flp) {
236+
v.warnings = append(v.warnings, "Mismatch detected between spec.agent.ebpf.advanced.scheduling and spec.processor.advanced.scheduling. In Direct mode, it can lead to inconsistent pod scheduling that would result in errors in the flow collection process.")
237+
}
238+
}
239+
}
240+
223241
func (v *validator) validateFLPLogTypes() {
224242
if v.fc.Processor.LogTypes != nil && *v.fc.Processor.LogTypes == LogTypeAll {
225243
v.warnings = append(v.warnings, "Enabling all log types (in spec.processor.logTypes) has a high impact on resources footprint")

api/flowcollector/v1beta2/flowcollector_validation_webhook_test.go

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

77
"github.com/netobserv/network-observability-operator/internal/pkg/cluster"
88
"github.com/stretchr/testify/assert"
9+
corev1 "k8s.io/api/core/v1"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
"k8s.io/apimachinery/pkg/util/intstr"
1112
"k8s.io/utils/ptr"
@@ -728,6 +729,165 @@ func TestValidateFLP(t *testing.T) {
728729
}
729730
}
730731

732+
func TestValidateScheduling(t *testing.T) {
733+
mismatchWarning := "Mismatch detected between spec.agent.ebpf.advanced.scheduling and spec.processor.advanced.scheduling. In Direct mode, it can lead to inconsistent pod scheduling that would result in errors in the flow collection process."
734+
tests := []struct {
735+
name string
736+
fc *FlowCollector
737+
expectedError string
738+
expectedWarnings admission.Warnings
739+
ocpVersion string
740+
}{
741+
{
742+
name: "Valid default (Direct)",
743+
fc: &FlowCollector{
744+
ObjectMeta: metav1.ObjectMeta{
745+
Name: "cluster",
746+
},
747+
Spec: FlowCollectorSpec{
748+
DeploymentModel: DeploymentModelDirect,
749+
},
750+
},
751+
},
752+
{
753+
name: "Invalid Agent scheduling",
754+
fc: &FlowCollector{
755+
ObjectMeta: metav1.ObjectMeta{
756+
Name: "cluster",
757+
},
758+
Spec: FlowCollectorSpec{
759+
DeploymentModel: DeploymentModelDirect,
760+
Agent: FlowCollectorAgent{
761+
EBPF: FlowCollectorEBPF{
762+
Advanced: &AdvancedAgentConfig{
763+
Scheduling: &SchedulingConfig{
764+
Tolerations: []corev1.Toleration{{Key: "key"}},
765+
},
766+
},
767+
},
768+
},
769+
},
770+
},
771+
expectedWarnings: admission.Warnings{mismatchWarning},
772+
},
773+
{
774+
name: "Invalid FLP scheduling",
775+
fc: &FlowCollector{
776+
ObjectMeta: metav1.ObjectMeta{
777+
Name: "cluster",
778+
},
779+
Spec: FlowCollectorSpec{
780+
DeploymentModel: DeploymentModelDirect,
781+
Processor: FlowCollectorFLP{
782+
Advanced: &AdvancedProcessorConfig{
783+
Scheduling: &SchedulingConfig{
784+
Tolerations: []corev1.Toleration{{Key: "key"}},
785+
},
786+
},
787+
},
788+
},
789+
},
790+
expectedWarnings: admission.Warnings{mismatchWarning},
791+
},
792+
{
793+
name: "Invalid FLP and Agent scheduling",
794+
fc: &FlowCollector{
795+
ObjectMeta: metav1.ObjectMeta{
796+
Name: "cluster",
797+
},
798+
Spec: FlowCollectorSpec{
799+
DeploymentModel: DeploymentModelDirect,
800+
Agent: FlowCollectorAgent{
801+
EBPF: FlowCollectorEBPF{
802+
Advanced: &AdvancedAgentConfig{
803+
Scheduling: &SchedulingConfig{
804+
Tolerations: []corev1.Toleration{{Key: "key1"}},
805+
},
806+
},
807+
},
808+
},
809+
Processor: FlowCollectorFLP{
810+
Advanced: &AdvancedProcessorConfig{
811+
Scheduling: &SchedulingConfig{
812+
Tolerations: []corev1.Toleration{{Key: "key2"}},
813+
},
814+
},
815+
},
816+
},
817+
},
818+
expectedWarnings: admission.Warnings{mismatchWarning},
819+
},
820+
{
821+
name: "Valid FLP and Agent scheduling",
822+
fc: &FlowCollector{
823+
ObjectMeta: metav1.ObjectMeta{
824+
Name: "cluster",
825+
},
826+
Spec: FlowCollectorSpec{
827+
DeploymentModel: DeploymentModelDirect,
828+
Agent: FlowCollectorAgent{
829+
EBPF: FlowCollectorEBPF{
830+
Advanced: &AdvancedAgentConfig{
831+
Scheduling: &SchedulingConfig{
832+
Tolerations: []corev1.Toleration{{Key: "same_key"}},
833+
},
834+
},
835+
},
836+
},
837+
Processor: FlowCollectorFLP{
838+
Advanced: &AdvancedProcessorConfig{
839+
Scheduling: &SchedulingConfig{
840+
Tolerations: []corev1.Toleration{{Key: "same_key"}},
841+
},
842+
},
843+
},
844+
},
845+
},
846+
},
847+
{
848+
name: "Valid default (Kafka)",
849+
fc: &FlowCollector{
850+
ObjectMeta: metav1.ObjectMeta{
851+
Name: "cluster",
852+
},
853+
Spec: FlowCollectorSpec{
854+
DeploymentModel: DeploymentModelKafka,
855+
},
856+
},
857+
},
858+
{
859+
name: "No inconsistent scheduling with Kafka",
860+
fc: &FlowCollector{
861+
ObjectMeta: metav1.ObjectMeta{
862+
Name: "cluster",
863+
},
864+
Spec: FlowCollectorSpec{
865+
Processor: FlowCollectorFLP{
866+
Advanced: &AdvancedProcessorConfig{
867+
Scheduling: &SchedulingConfig{
868+
Tolerations: []corev1.Toleration{{Key: "key"}},
869+
},
870+
},
871+
},
872+
},
873+
},
874+
},
875+
}
876+
877+
CurrentClusterInfo = &cluster.Info{}
878+
r := FlowCollector{}
879+
for _, test := range tests {
880+
CurrentClusterInfo.MockOpenShiftVersion(test.ocpVersion)
881+
warnings, err := r.Validate(context.TODO(), test.fc)
882+
if test.expectedError == "" {
883+
assert.NoError(t, err, test.name)
884+
} else {
885+
assert.ErrorContains(t, err, test.expectedError, test.name)
886+
}
887+
assert.Equal(t, test.expectedWarnings, warnings, test.name)
888+
}
889+
}
890+
731891
func TestElligibleMetrics(t *testing.T) {
732892
met, tot := GetElligibleMetricsForAlert(AlertPacketDropsByKernel, &AlertVariant{
733893
GroupBy: GroupByNamespace,

0 commit comments

Comments
 (0)