Skip to content

Commit 260974e

Browse files
committed
reconciler/apibinding: check conflict via bound APIs in bindings, not exports
Signed-off-by: Dr. Stefan Schimanski <[email protected]>
1 parent fc1e66a commit 260974e

File tree

5 files changed

+28
-58
lines changed

5 files changed

+28
-58
lines changed

pkg/admission/apibinding/validation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func ValidateAPIBindingUpdate(oldBinding, newBinding *apisv1alpha1.APIBinding) f
5454
// ValidateAPIBindingReference validates an APIBinding's BindingReference.
5555
func ValidateAPIBindingReference(reference apisv1alpha1.BindingReference, path *field.Path) field.ErrorList {
5656
allErrs := field.ErrorList{}
57-
57+
5858
if reference.Export == nil {
5959
allErrs = append(allErrs, field.Required(path.Child("export"), ""))
6060
} else if reference.Export.Name == "" {

pkg/reconciler/apis/apibinding/apibinding_reconcile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ func (r *bindingReconciler) reconcile(ctx context.Context, apiBinding *apisv1alp
211211

212212
var needToWaitForRequeueWhenEstablished []string
213213

214-
checker, err := newConflictChecker(logicalcluster.From(apiBinding), r.listAPIBindings, r.getAPIExportByPath, r.getAPIResourceSchema, r.getCRD, r.listCRDs)
214+
checker, err := newConflictChecker(logicalcluster.From(apiBinding), r.listAPIBindings, r.getAPIResourceSchema, r.getCRD, r.listCRDs)
215215
if err != nil {
216216
return reconcileStatusContinue, err
217217
}

pkg/reconciler/apis/apibinding/apibinding_reconcile_test.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ func TestReconcileBinding(t *testing.T) {
479479
},
480480
}
481481

482-
if name == "anotherwidgetsuid" {
482+
switch name {
483+
case "anotherwidgetsuid":
483484
crd.Spec.Group = "kcp.io"
484485
crd.Spec.Names = apiextensionsv1.CustomResourceDefinitionNames{
485486
Plural: "widgets",
@@ -488,10 +489,29 @@ func TestReconcileBinding(t *testing.T) {
488489
Plural: "widgets",
489490
}
490491
return crd, nil
492+
case "uid1":
493+
crd.Spec.Group = "someresources.mygroup"
494+
crd.Spec.Names = apiextensionsv1.CustomResourceDefinitionNames{
495+
Plural: "todays",
496+
}
497+
crd.Status.AcceptedNames = apiextensionsv1.CustomResourceDefinitionNames{
498+
Plural: "todays",
499+
}
500+
return crd, nil
501+
case "uid2":
502+
crd.Spec.Group = "someresources.anothergroup"
503+
crd.Spec.Names = apiextensionsv1.CustomResourceDefinitionNames{
504+
Plural: "todays",
505+
}
506+
crd.Status.AcceptedNames = apiextensionsv1.CustomResourceDefinitionNames{
507+
Plural: "todays",
508+
}
509+
return crd, nil
510+
default:
491511
}
492512

493513
if !tc.crdExists {
494-
return nil, apierrors.NewNotFound(schema.GroupResource{}, "")
514+
return nil, apierrors.NewNotFound(schema.GroupResource{}, name)
495515
}
496516

497517
if tc.crdEstablished {

pkg/reconciler/apis/apibinding/conflict_checker.go

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ func (u byUID) Swap(i, j int) { u[i], u[j] = u[j], u[i] }
3737

3838
type conflictChecker struct {
3939
listAPIBindings func(clusterName logicalcluster.Name) ([]*apisv1alpha1.APIBinding, error)
40-
getAPIExportByPath func(path logicalcluster.Path, name string) (*apisv1alpha1.APIExport, error)
4140
getAPIResourceSchema func(clusterName logicalcluster.Name, name string) (*apisv1alpha1.APIResourceSchema, error)
4241
getCRD func(clusterName logicalcluster.Name, name string) (*apiextensionsv1.CustomResourceDefinition, error)
4342
listCRDs func(clusterName logicalcluster.Name) ([]*apiextensionsv1.CustomResourceDefinition, error)
@@ -50,14 +49,12 @@ type conflictChecker struct {
5049
// newConflictChecker creates a CRD conflict checker for the given cluster.
5150
func newConflictChecker(clusterName logicalcluster.Name,
5251
listAPIBindings func(clusterName logicalcluster.Name) ([]*apisv1alpha1.APIBinding, error),
53-
getAPIExportByPath func(path logicalcluster.Path, name string) (*apisv1alpha1.APIExport, error),
5452
getAPIResourceSchema func(clusterName logicalcluster.Name, name string) (*apisv1alpha1.APIResourceSchema, error),
5553
getCRD func(clusterName logicalcluster.Name, name string) (*apiextensionsv1.CustomResourceDefinition, error),
5654
listCRDs func(clusterName logicalcluster.Name) ([]*apiextensionsv1.CustomResourceDefinition, error),
5755
) (*conflictChecker, error) {
5856
ncc := &conflictChecker{
5957
listAPIBindings: listAPIBindings,
60-
getAPIExportByPath: getAPIExportByPath,
6158
getAPIResourceSchema: getAPIResourceSchema,
6259
getCRD: getCRD,
6360
listCRDs: listCRDs,
@@ -71,35 +68,8 @@ func newConflictChecker(clusterName logicalcluster.Name,
7168
return nil, err
7269
}
7370
for _, b := range bindings {
74-
if b.Spec.Reference.Export == nil {
75-
// this should not happen because of validation.
76-
return nil, fmt.Errorf("APIBinding %s|%s has no cluster reference", logicalcluster.From(b), b.Name)
77-
}
78-
path := logicalcluster.NewPath(b.Spec.Reference.Export.Path)
79-
if path.Empty() {
80-
path = logicalcluster.From(b).Path()
81-
}
82-
apiExport, err := ncc.getAPIExportByPath(path, b.Spec.Reference.Export.Name)
83-
if err != nil {
84-
return nil, err
85-
}
86-
87-
boundSchemaUIDs := sets.New[string]()
88-
for _, boundResource := range b.Status.BoundResources {
89-
boundSchemaUIDs.Insert(boundResource.Schema.UID)
90-
}
91-
92-
for _, schemaName := range apiExport.Spec.LatestResourceSchemas {
93-
schema, err := ncc.getAPIResourceSchema(logicalcluster.From(apiExport), schemaName)
94-
if err != nil {
95-
return nil, err
96-
}
97-
98-
if !boundSchemaUIDs.Has(string(schema.UID)) {
99-
continue
100-
}
101-
102-
crd, err := ncc.getCRD(SystemBoundCRDsClusterName, string(schema.UID))
71+
for _, br := range b.Status.BoundResources {
72+
crd, err := ncc.getCRD(SystemBoundCRDsClusterName, br.Schema.UID)
10373
if err != nil {
10474
return nil, err
10575
}
@@ -121,6 +91,8 @@ func newConflictChecker(clusterName logicalcluster.Name,
12191
return ncc, nil
12292
}
12393

94+
// Check checks if the given schema from the given APIBinding conflicts with any
95+
// CRD or any other APIBinding.
12496
func (ncc *conflictChecker) Check(binding *apisv1alpha1.APIBinding, s *apisv1alpha1.APIResourceSchema) error {
12597
for _, crd := range ncc.crds {
12698
if other, found := ncc.crdToBinding[crd.Name]; found && other.Name == binding.Name {

pkg/reconciler/apis/apibinding/conflict_checker_test.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,6 @@ func TestNameConflictCheckerGetBoundCRDs(t *testing.T) {
6060
).
6161
Build()
6262

63-
apiExports := map[string]*apisv1alpha1.APIExport{
64-
"export0": {
65-
Spec: apisv1alpha1.APIExportSpec{
66-
LatestResourceSchemas: []string{"export0-schema1"},
67-
},
68-
},
69-
"export1": {
70-
Spec: apisv1alpha1.APIExportSpec{
71-
LatestResourceSchemas: []string{"export1-schema1", "export1-schema2", "export1-schema3"},
72-
},
73-
},
74-
"export2": {
75-
Spec: apisv1alpha1.APIExportSpec{
76-
LatestResourceSchemas: []string{"export2-schema1", "export2-schema2", "export2-schema3"},
77-
},
78-
},
79-
}
80-
8163
apiResourceSchemas := map[string]*apisv1alpha1.APIResourceSchema{
8264
"export0-schema1": {ObjectMeta: metav1.ObjectMeta{UID: "e0-s1"}},
8365
"export1-schema1": {ObjectMeta: metav1.ObjectMeta{UID: "e1-s1"}},
@@ -96,9 +78,6 @@ func TestNameConflictCheckerGetBoundCRDs(t *testing.T) {
9678
existingBinding2,
9779
}, nil
9880
},
99-
func(path logicalcluster.Path, name string) (*apisv1alpha1.APIExport, error) {
100-
return apiExports[name], nil
101-
},
10281
func(clusterName logicalcluster.Name, name string) (*apisv1alpha1.APIResourceSchema, error) {
10382
return apiResourceSchemas[name], nil
10483
},
@@ -276,7 +255,6 @@ func TestCRDs(t *testing.T) {
276255
func(clusterName logicalcluster.Name) ([]*apisv1alpha1.APIBinding, error) {
277256
return nil, nil
278257
},
279-
func(path logicalcluster.Path, name string) (*apisv1alpha1.APIExport, error) { return nil, nil },
280258
func(clusterName logicalcluster.Name, name string) (*apisv1alpha1.APIResourceSchema, error) {
281259
return nil, nil
282260
},

0 commit comments

Comments
 (0)