@@ -18,13 +18,15 @@ package webhook
1818
1919import (
2020 "context"
21+ "fmt"
2122 "strconv"
2223
24+ apierrors "k8s.io/apimachinery/pkg/api/errors"
2325 "k8s.io/apimachinery/pkg/util/validation/field"
2426 "sigs.k8s.io/controller-runtime/pkg/client"
2527
2628 enterpriseApi "github.com/splunk/splunk-operator/api/v4"
27- hba "github.com/splunk/splunk-operator/pkg/postgresql/cluster/core"
29+ core "github.com/splunk/splunk-operator/pkg/postgresql/cluster/core"
2830)
2931
3032// ValidatePostgresClusterCreate validates a PostgresCluster on CREATE.
@@ -33,7 +35,7 @@ func ValidatePostgresClusterCreate(obj *enterpriseApi.PostgresCluster, reader cl
3335
3436 if len (obj .Spec .PgHBA ) > 0 {
3537 pgHBAPath := field .NewPath ("spec" ).Child ("pgHBA" )
36- for _ , re := range hba .ValidateRules (obj .Spec .PgHBA ) {
38+ for _ , re := range core .ValidateRules (obj .Spec .PgHBA ) {
3739 allErrs = append (allErrs , field .Invalid (
3840 pgHBAPath .Index (re .Index ),
3941 obj .Spec .PgHBA [re .Index ],
@@ -58,81 +60,62 @@ func validateAgainstClass(obj *enterpriseApi.PostgresCluster, reader client.Read
5860
5961 class := & enterpriseApi.PostgresClusterClass {}
6062 if err := reader .Get (context .Background (), client.ObjectKey {Name : obj .Spec .Class }, class ); err != nil {
61- allErrs = append (allErrs , field .Invalid (
62- field .NewPath ("spec" ).Child ("class" ),
63- obj .Spec .Class ,
64- "referenced PostgresClusterClass not found" ))
63+ classPath := field .NewPath ("spec" ).Child ("class" )
64+ if apierrors .IsNotFound (err ) {
65+ allErrs = append (allErrs , field .Invalid (classPath , obj .Spec .Class ,
66+ "referenced PostgresClusterClass not found" ))
67+ } else {
68+ allErrs = append (allErrs , field .InternalError (classPath ,
69+ fmt .Errorf ("failed to look up PostgresClusterClass %q: %w" , obj .Spec .Class , err )))
70+ }
6571 return allErrs
6672 }
6773
68- classConfig := class .Spec .Config
69-
70- mergedInstances := obj .Spec .Instances
71- mergedVersion := obj .Spec .PostgresVersion
72- mergedStorage := obj .Spec .Storage
73- if classConfig != nil {
74- if mergedInstances == nil {
75- mergedInstances = classConfig .Instances
74+ merged , err := core .GetMergedConfig (class , obj )
75+ if err != nil {
76+ specPath := field .NewPath ("spec" )
77+ if merged == nil || merged .Spec .Instances == nil {
78+ allErrs = append (allErrs , field .Required (specPath .Child ("instances" ),
79+ "must be set in PostgresCluster or PostgresClusterClass" ))
7680 }
77- if mergedVersion == nil {
78- mergedVersion = classConfig .PostgresVersion
81+ if merged == nil || merged .Spec .PostgresVersion == nil {
82+ allErrs = append (allErrs , field .Required (specPath .Child ("postgresVersion" ),
83+ "must be set in PostgresCluster or PostgresClusterClass" ))
7984 }
80- if mergedStorage == nil {
81- mergedStorage = classConfig .Storage
85+ if merged == nil || merged .Spec .Storage == nil {
86+ allErrs = append (allErrs , field .Required (specPath .Child ("storage" ),
87+ "must be set in PostgresCluster or PostgresClusterClass" ))
8288 }
83- }
84- specPath := field .NewPath ("spec" )
85- if mergedInstances == nil {
86- allErrs = append (allErrs , field .Required (specPath .Child ("instances" ),
87- "must be set in PostgresCluster or PostgresClusterClass" ))
88- }
89- if mergedVersion == nil {
90- allErrs = append (allErrs , field .Required (specPath .Child ("postgresVersion" ),
91- "must be set in PostgresCluster or PostgresClusterClass" ))
92- }
93- if mergedStorage == nil {
94- allErrs = append (allErrs , field .Required (specPath .Child ("storage" ),
95- "must be set in PostgresCluster or PostgresClusterClass" ))
96- }
97-
98- if classConfig == nil {
9989 return allErrs
10090 }
10191
102- if obj .Spec .Storage != nil && classConfig .Storage != nil {
103- if obj .Spec .Storage .Cmp (* classConfig .Storage ) < 0 {
104- allErrs = append (allErrs , field .Invalid (
105- field .NewPath ("spec" ).Child ("storage" ),
106- obj .Spec .Storage .String (),
107- "storage cannot be lower than class default (" + classConfig .Storage .String ()+ ")" ))
108- }
109- }
110-
111- if obj .Spec .PostgresVersion != nil && classConfig .PostgresVersion != nil {
112- clusterMajor , clusterMinor := parseVersion (* obj .Spec .PostgresVersion )
113- classMajor , classMinor := parseVersion (* classConfig .PostgresVersion )
114- if clusterMajor > 0 && classMajor > 0 {
115- versionTooLow := clusterMajor < classMajor ||
116- (clusterMajor == classMajor && classMinor >= 0 && clusterMinor >= 0 && clusterMinor < classMinor )
117- if versionTooLow {
118- allErrs = append (allErrs , field .Invalid (
119- field .NewPath ("spec" ).Child ("postgresVersion" ),
120- * obj .Spec .PostgresVersion ,
121- "postgresVersion cannot be lower than class default (" + * classConfig .PostgresVersion + ")" ))
92+ if classConfig := class .Spec .Config ; classConfig != nil {
93+ if obj .Spec .PostgresVersion != nil && classConfig .PostgresVersion != nil {
94+ clusterMajor , clusterMinor := parseVersion (* obj .Spec .PostgresVersion )
95+ classMajor , classMinor := parseVersion (* classConfig .PostgresVersion )
96+ if clusterMajor > 0 && classMajor > 0 {
97+ versionTooLow := clusterMajor < classMajor ||
98+ (clusterMajor == classMajor && classMinor >= 0 && clusterMinor >= 0 && clusterMinor < classMinor )
99+ if versionTooLow {
100+ allErrs = append (allErrs , field .Invalid (
101+ field .NewPath ("spec" ).Child ("postgresVersion" ),
102+ * obj .Spec .PostgresVersion ,
103+ "postgresVersion cannot be lower than class default (" + * classConfig .PostgresVersion + ")" ))
104+ }
122105 }
123106 }
124- }
125107
126- if obj .Spec .ConnectionPoolerEnabled != nil && * obj .Spec .ConnectionPoolerEnabled {
127- classDisabled := classConfig .ConnectionPoolerEnabled == nil || ! * classConfig .ConnectionPoolerEnabled
128- if classDisabled {
108+ poolerEnabled := ( obj .Spec .ConnectionPoolerEnabled != nil && * obj .Spec .ConnectionPoolerEnabled ) ||
109+ ( obj . Spec . ConnectionPoolerEnabled == nil && classConfig .ConnectionPoolerEnabled != nil && * classConfig .ConnectionPoolerEnabled )
110+ if poolerEnabled && ( class . Spec . CNPG == nil || class . Spec . CNPG . ConnectionPooler == nil ) {
129111 allErrs = append (allErrs , field .Invalid (
130112 field .NewPath ("spec" ).Child ("connectionPoolerEnabled" ),
131113 true ,
132- "connectionPoolerEnabled cannot be enabled when disabled in PostgresClusterClass" ))
114+ "connection pooler requires cnpg.connectionPooler configuration in PostgresClusterClass" ))
133115 }
134116 }
135117
118+ _ = merged
136119 return allErrs
137120}
138121
0 commit comments