diff --git a/internal/controller/validator.go b/internal/controller/validator.go index 482130daa3b..1a8a47a95ed 100644 --- a/internal/controller/validator.go +++ b/internal/controller/validator.go @@ -70,8 +70,10 @@ func (r *DataProtectionApplicationReconciler) ValidateDataProtectionCR(log logr. // Ensure DPA spec.configuration.nodeAgent.PodConfig is not different from spec.configuration.nodeAgent.LoadAffinityConfig // If LoadAffinityConfig is set, it will be used instead of PodConfig; however, if both are set, they must be identical. + // Only validate when podConfig.nodeSelector is explicitly set; an empty podConfig (e.g. only resourceAllocations) is valid alongside loadAffinity. if r.dpa.Spec.Configuration.NodeAgent != nil && r.dpa.Spec.Configuration.NodeAgent.PodConfig != nil && + len(r.dpa.Spec.Configuration.NodeAgent.PodConfig.NodeSelector) > 0 && r.dpa.Spec.Configuration.NodeAgent.LoadAffinityConfig != nil { if len(r.dpa.Spec.Configuration.NodeAgent.LoadAffinityConfig) > 1 { diff --git a/internal/controller/validator_test.go b/internal/controller/validator_test.go index 063cb69b695..02e5ef2df7b 100644 --- a/internal/controller/validator_test.go +++ b/internal/controller/validator_test.go @@ -2466,6 +2466,48 @@ func TestDPAReconciler_ValidateDataProtectionCR(t *testing.T) { }, wantErr: false, }, + { + // OADP-7017: podConfig with resourceAllocations but no nodeSelector alongside loadAffinity using matchExpressions should be valid + name: "[valid] PodConfig with resourceAllocations but no nodeSelector and LoadAffinityConfig with matchExpressions only", + dpa: &oadpv1alpha1.DataProtectionApplication{ + Spec: oadpv1alpha1.DataProtectionApplicationSpec{ + BackupImages: ptr.To(false), + Configuration: &oadpv1alpha1.ApplicationConfig{ + Velero: &oadpv1alpha1.VeleroConfig{ + NoDefaultBackupLocation: true, + }, + NodeAgent: &oadpv1alpha1.NodeAgentConfig{ + NodeAgentCommonFields: oadpv1alpha1.NodeAgentCommonFields{ + PodConfig: &oadpv1alpha1.PodConfig{ + ResourceAllocations: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + corev1.ResourceMemory: resource.MustParse("128Mi"), + }, + }, + }, + }, + NodeAgentConfigMapSettings: oadpv1alpha1.NodeAgentConfigMapSettings{ + LoadAffinityConfig: []*oadpv1alpha1.LoadAffinity{ + { + NodeSelector: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "foo", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"bar"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + wantErr: false, + }, { name: "[valid] Only LoadAffinityConfig is set with MatchExpressions", dpa: &oadpv1alpha1.DataProtectionApplication{