Skip to content
This repository was archived by the owner on Apr 17, 2025. It is now read-only.

Commit 74f1e20

Browse files
committed
fix: Use GVK instead of GR to check if the given resource is enforced type
1 parent 572c781 commit 74f1e20

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

internal/hncconfig/reconciler.go

+31-1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ func (r *Reconciler) ensureEnforcedTypes(inst *api.HNCConfiguration) error {
146146
// to retry but only set conditions since the configuration may be incorrect.
147147
func (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}
151152
// Look if the resource exists in the API server.
@@ -164,7 +165,7 @@ func (r *Reconciler) reconcileConfigTypes(inst *api.HNCConfiguration) {
164165
log := r.Log.WithValues("resource", gr, "appliedMode", rsc.Mode)
165166
msg := ""
166167
// Set a different message if the type is enforced by HNC.
167-
if api.IsEnforcedType(rsc) {
168+
if gvkChecker.isEnforced(gvk) {
168169
msg = fmt.Sprintf("The sync mode for %q is enforced by HNC as %q and cannot be overridden", gr, api.Propagate)
169170
log.Info("The sync mode for this resource is enforced by HNC and cannot be overridden")
170171
} else {
@@ -541,3 +542,32 @@ func reasonForGVKError(err error) string {
541542
}
542543
return reason
543544
}
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+
}

internal/hncconfig/validator.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,10 @@ func (v *Validator) handle(inst *api.HNCConfiguration) admission.Response {
9191

9292
func (v *Validator) validateTypes(inst *api.HNCConfiguration, ts gvkSet) admission.Response {
9393
allErrs := field.ErrorList{}
94+
gvkChecker := newGVKChecker(v.mapper)
9495
for i, r := range inst.Spec.Resources {
9596
gr := schema.GroupResource{Group: r.Group, Resource: r.Resource}
9697
fldPath := field.NewPath("spec", "resources").Index(i)
97-
// Validate the type configured is not an HNC enforced type.
98-
if api.IsEnforcedType(r) {
99-
fldErr := field.Invalid(fldPath, gr, "always uses the 'Propagate' mode and cannot be configured")
100-
allErrs = append(allErrs, fldErr)
101-
}
10298

10399
// Validate the resource exists and is namespaced. And convert GR to GVK.
104100
// We use GVK because we will need to checkForest() later to avoid source
@@ -109,6 +105,12 @@ func (v *Validator) validateTypes(inst *api.HNCConfiguration, ts gvkSet) admissi
109105
allErrs = append(allErrs, fldErr)
110106
}
111107

108+
// Validate the type configured is not an HNC enforced type.
109+
if gvkChecker.isEnforced(gvk) {
110+
fldErr := field.Invalid(fldPath, gr, "always uses the 'Propagate' mode and cannot be configured")
111+
allErrs = append(allErrs, fldErr)
112+
}
113+
112114
// Validate if the configuration of a type already exists. Each type should
113115
// only have one configuration.
114116
if _, exists := ts[gvk]; exists {

internal/hncconfig/validator_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ var (
2424
gr2gvk = map[schema.GroupResource]schema.GroupVersionKind{
2525
{Group: api.RBACGroup, Resource: api.RoleResource}: {Group: api.RBACGroup, Version: "v1", Kind: api.RoleKind},
2626
{Group: api.RBACGroup, Resource: api.RoleBindingResource}: {Group: api.RBACGroup, Version: "v1", Kind: api.RoleBindingKind},
27+
{Group: api.RBACGroup, Resource: "role"}: {Group: api.RBACGroup, Version: "v1", Kind: api.RoleKind},
28+
{Group: api.RBACGroup, Resource: "rolebinding"}: {Group: api.RBACGroup, Version: "v1", Kind: api.RoleBindingKind},
29+
{Resource: api.RoleResource}: {Group: api.RBACGroup, Version: "v1", Kind: api.RoleKind},
30+
{Resource: api.RoleBindingResource}: {Group: api.RBACGroup, Version: "v1", Kind: api.RoleBindingKind},
2731
{Group: "", Resource: "secrets"}: {Group: "", Version: "v1", Kind: "Secret"},
2832
{Group: "", Resource: "resourcequotas"}: {Group: "", Version: "v1", Kind: "ResourceQuota"},
2933
}
@@ -87,6 +91,22 @@ func TestRBACTypes(t *testing.T) {
8791
},
8892
allow: false,
8993
},
94+
{
95+
name: "Configure redundant enforced resources in a singular manner",
96+
configs: []api.ResourceSpec{
97+
{Group: api.RBACGroup, Resource: "role", Mode: api.AllowPropagate},
98+
{Group: api.RBACGroup, Resource: "rolebinding", Mode: api.AllowPropagate},
99+
},
100+
allow: false,
101+
},
102+
{
103+
name: "Configure redundant enforced resources without specifying group",
104+
configs: []api.ResourceSpec{
105+
{Resource: api.RoleResource, Mode: api.AllowPropagate},
106+
{Resource: api.RoleBindingResource, Mode: api.AllowPropagate},
107+
},
108+
allow: false,
109+
},
90110
}
91111

92112
for _, tc := range tests {

0 commit comments

Comments
 (0)