@@ -146,15 +146,26 @@ func (r *Reconciler) ensureEnforcedTypes(inst *api.HNCConfiguration) error {
146146// to retry but only set conditions since the configuration may be incorrect.
147147func (r * Reconciler ) reconcileConfigTypes (inst * api.HNCConfiguration ) {
148148 // Get valid settings in the spec.resources of the `config` singleton.
149+ gvkChecker := newGVKChecker (r .resourceMapper )
149150 for _ , rsc := range inst .Spec .Resources {
150151 gr := schema.GroupResource {Group : rsc .Group , Resource : rsc .Resource }
151- // If there are multiple configurations of the same type, we will follow the
152+ // Look if the resource exists in the API server.
153+ gvk , err := r .resourceMapper .NamespacedKindFor (gr )
154+ if err != nil {
155+ // Log error and write conditions, but don't early exit since the other types can still be reconciled.
156+ r .Log .Error (err , "while trying to reconcile the configuration" , "type" , gr , "mode" , rsc .Mode )
157+ r .writeCondition (inst , api .ConditionBadTypeConfiguration , reasonForGVKError (err ), err .Error ())
158+ continue
159+ }
160+
161+ // If there are multiple configurations of the same GVK, we will follow the
152162 // first configuration and ignore the rest.
153- if gvkMode , exist := r .activeGVKMode [gr ]; exist {
154- log := r .Log .WithValues ("resource" , gr , "appliedMode" , gvkMode .mode )
163+ if firstGR , exist := r .activeGR [gvk ]; exist {
164+ gvkMode := r .activeGVKMode [firstGR ]
165+ log := r .Log .WithValues ("resource" , gr , "appliedMode" , rsc .Mode )
155166 msg := ""
156167 // Set a different message if the type is enforced by HNC.
157- if api . IsEnforcedType ( rsc ) {
168+ if gvkChecker . isEnforced ( gvk ) {
158169 msg = fmt .Sprintf ("The sync mode for %q is enforced by HNC as %q and cannot be overridden" , gr , api .Propagate )
159170 log .Info ("The sync mode for this resource is enforced by HNC and cannot be overridden" )
160171 } else {
@@ -165,14 +176,6 @@ func (r *Reconciler) reconcileConfigTypes(inst *api.HNCConfiguration) {
165176 continue
166177 }
167178
168- // Look if the resource exists in the API server.
169- gvk , err := r .resourceMapper .NamespacedKindFor (gr )
170- if err != nil {
171- // Log error and write conditions, but don't early exit since the other types can still be reconciled.
172- r .Log .Error (err , "while trying to reconcile the configuration" , "type" , gr , "mode" , rsc .Mode )
173- r .writeCondition (inst , api .ConditionBadTypeConfiguration , reasonForGVKError (err ), err .Error ())
174- continue
175- }
176179 r .activeGVKMode [gr ] = gvkMode {gvk , rsc .Mode }
177180 r .activeGR [gvk ] = gr
178181 }
@@ -539,3 +542,32 @@ func reasonForGVKError(err error) string {
539542 }
540543 return reason
541544}
545+
546+ // gvkChecker checks if a GVK is an enforced type.
547+ // It is needed to check duplicated types in ResourceSpec using GVK instead of GR,
548+ // since the user-given GRs might include some ambiguity.
549+ // (e.g. singular/plural, empty group is handled as corev1).
550+ type gvkChecker struct {
551+ enforcedGVKs []schema.GroupVersionKind
552+ }
553+
554+ func newGVKChecker (mapper resourceMapper ) * gvkChecker {
555+ var enforcedGVKs []schema.GroupVersionKind
556+ for _ , enforcedType := range api .EnforcedTypes {
557+ enforcedGVK , _ := mapper .NamespacedKindFor (schema.GroupResource {
558+ Group : enforcedType .Group ,
559+ Resource : enforcedType .Resource ,
560+ })
561+ enforcedGVKs = append (enforcedGVKs , enforcedGVK )
562+ }
563+ return & gvkChecker {enforcedGVKs }
564+ }
565+
566+ func (c * gvkChecker ) isEnforced (gvk schema.GroupVersionKind ) bool {
567+ for _ , enforcedGVK := range c .enforcedGVKs {
568+ if gvk == enforcedGVK {
569+ return true
570+ }
571+ }
572+ return false
573+ }
0 commit comments