Skip to content

Commit 382725f

Browse files
committed
update remaining controllers to perform the new routine to determine local/remote GVKs
On-behalf-of: @SAP [email protected]
1 parent a8bb1e8 commit 382725f

File tree

4 files changed

+85
-40
lines changed

4 files changed

+85
-40
lines changed

internal/controller/sync/controller.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,30 @@ func Create(
7878
) (controller.Controller, error) {
7979
log = log.Named(ControllerName)
8080

81+
// find the local CRD so we know the actual local object scope
82+
localCRD, err := discoveryClient.RetrieveCRD(ctx, projection.PublishedResourceSourceGK(pubRes))
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to find local CRD: %w", err)
85+
}
86+
8187
// create a dummy that represents the type used on the local service cluster
82-
localGVK := projection.PublishedResourceSourceGVK(pubRes)
88+
localGVK, err := projection.PublishedResourceSourceGVK(localCRD, pubRes)
89+
if err != nil {
90+
return nil, err
91+
}
92+
8393
localDummy := &unstructured.Unstructured{}
8494
localDummy.SetGroupVersionKind(localGVK)
8595

8696
// create a dummy unstructured object with the projected GVK inside the workspace
87-
remoteGVK := projection.PublishedResourceProjectedGVK(pubRes)
88-
remoteDummy := &unstructured.Unstructured{}
89-
remoteDummy.SetGroupVersionKind(remoteGVK)
90-
91-
// find the local CRD so we know the actual local object scope
92-
localCRD, err := discoveryClient.RetrieveCRD(ctx, localGVK)
97+
remoteGVK, err := projection.PublishedResourceProjectedGVK(localCRD, pubRes)
9398
if err != nil {
94-
return nil, fmt.Errorf("failed to find local CRD: %w", err)
99+
return nil, err
95100
}
96101

102+
remoteDummy := &unstructured.Unstructured{}
103+
remoteDummy.SetGroupVersionKind(remoteGVK)
104+
97105
// create the syncer that holds the meat&potatoes of the synchronization logic
98106
mutator := mutation.NewMutator(pubRes.Spec.Mutation)
99107
syncer, err := sync.NewResourceSyncer(log, localManager.GetClient(), virtualWorkspaceCluster.GetClient(), pubRes, localCRD, mutator, stateNamespace, agentName)

internal/projection/projection.go

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,49 @@ func PublishedResourceSourceGK(pubRes *syncagentv1alpha1.PublishedResource) sche
3939
}
4040
}
4141

42-
// PublishedResourceProjectedGVK returns the effective GVK after the projection
43-
// rules have been applied according to the PublishedResource.
44-
func PublishedResourceProjectedGVK(pubRes *syncagentv1alpha1.PublishedResource) schema.GroupVersionKind {
45-
apiGroup := pubRes.Spec.Resource.APIGroup
46-
apiVersion := pubRes.Spec.Resource.Version
47-
kind := pubRes.Spec.Resource.Kind
48-
49-
if projection := pubRes.Spec.Projection; projection != nil {
50-
if v := projection.Group; v != "" {
51-
apiGroup = v
52-
}
42+
func PublishedResourceSourceGVK(crd *apiextensionsv1.CustomResourceDefinition, pubRes *syncagentv1alpha1.PublishedResource) (schema.GroupVersionKind, error) {
43+
storageVersion := getStorageVersion(crd)
44+
if storageVersion == "" {
45+
return schema.GroupVersionKind{}, errors.New("CRD does not contain a storage version")
46+
}
5347

54-
if v := projection.Version; v != "" {
55-
apiVersion = v
56-
}
48+
sourceGV := PublishedResourceSourceGK(pubRes)
5749

58-
if k := projection.Kind; k != "" {
59-
kind = k
50+
return schema.GroupVersionKind{
51+
Group: sourceGV.Group,
52+
Version: storageVersion,
53+
Kind: sourceGV.Kind,
54+
}, nil
55+
}
56+
57+
func getStorageVersion(crd *apiextensionsv1.CustomResourceDefinition) string {
58+
for _, version := range crd.Spec.Versions {
59+
if version.Storage {
60+
return version.Name
6061
}
6162
}
6263

63-
return schema.GroupVersionKind{
64-
Group: apiGroup,
65-
Version: apiVersion,
66-
Kind: kind,
64+
return ""
65+
}
66+
67+
// PublishedResourceProjectedGVK returns the effective GVK after the projection
68+
// rules have been applied according to the PublishedResource.
69+
func PublishedResourceProjectedGVK(originalCRD *apiextensionsv1.CustomResourceDefinition, pubRes *syncagentv1alpha1.PublishedResource) (schema.GroupVersionKind, error) {
70+
projectedCRD, err := ApplyProjection(originalCRD, pubRes)
71+
if err != nil {
72+
return schema.GroupVersionKind{}, fmt.Errorf("failed to project CRD: %w", err)
6773
}
74+
75+
storageVersion := getStorageVersion(projectedCRD)
76+
if storageVersion == "" {
77+
return schema.GroupVersionKind{}, errors.New("projected CRD does not contain a storage version")
78+
}
79+
80+
return schema.GroupVersionKind{
81+
Group: projectedCRD.Spec.Group,
82+
Version: storageVersion,
83+
Kind: projectedCRD.Spec.Names.Kind,
84+
}, nil
6885
}
6986

7087
func ApplyProjection(crd *apiextensionsv1.CustomResourceDefinition, pubRes *syncagentv1alpha1.PublishedResource) (*apiextensionsv1.CustomResourceDefinition, error) {

internal/projection/projection_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
syncagentv1alpha1 "github.com/kcp-dev/api-syncagent/sdk/apis/syncagent/v1alpha1"
23+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2324

2425
"k8s.io/apimachinery/pkg/runtime/schema"
2526
)
@@ -69,6 +70,22 @@ func TestPublishedResourceProjectedGVK(t *testing.T) {
6970
},
7071
}
7172

73+
crd := &apiextensionsv1.CustomResourceDefinition{
74+
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
75+
Group: apiGroup,
76+
Names: apiextensionsv1.CustomResourceDefinitionNames{
77+
Kind: kind,
78+
},
79+
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
80+
{
81+
Name: version,
82+
Served: true,
83+
Storage: true,
84+
},
85+
},
86+
},
87+
}
88+
7289
testcases := []struct {
7390
name string
7491
projection *syncagentv1alpha1.ResourceProjection
@@ -106,7 +123,10 @@ func TestPublishedResourceProjectedGVK(t *testing.T) {
106123
pr := pubRes.DeepCopy()
107124
pr.Spec.Projection = testcase.projection
108125

109-
gvk := PublishedResourceProjectedGVK(pr)
126+
gvk, err := PublishedResourceProjectedGVK(crd, pr)
127+
if err != nil {
128+
t.Fatalf("Unexpected error: %v", err)
129+
}
110130

111131
if gvk.Group != testcase.expected.Group {
112132
t.Errorf("Expected API group to be %q, but got %q.", testcase.expected.Group, gvk.Group)

internal/sync/syncer.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,25 @@ func NewResourceSyncer(
6363
agentName string,
6464
) (*ResourceSyncer, error) {
6565
// create a dummy that represents the type used on the local service cluster
66-
localGVK := projection.PublishedResourceSourceGVK(pubRes)
66+
localGVK, err := projection.PublishedResourceSourceGVK(localCRD, pubRes)
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
// create a dummy that represents the type used on the local service cluster
6772
localDummy := &unstructured.Unstructured{}
6873
localDummy.SetGroupVersionKind(localGVK)
6974

7075
// create a dummy unstructured object with the projected GVK inside the workspace
71-
remoteGVK := projection.PublishedResourceProjectedGVK(pubRes)
76+
remoteGVK, err := projection.PublishedResourceProjectedGVK(localCRD, pubRes)
77+
if err != nil {
78+
return nil, err
79+
}
7280

7381
// determine whether the CRD has a status subresource in the relevant version
7482
subresources := []string{}
75-
versionFound := false
76-
7783
for _, version := range localCRD.Spec.Versions {
78-
if version.Name == pubRes.Spec.Resource.Version {
79-
versionFound = true
80-
84+
if version.Name == localGVK.Version {
8185
if sr := version.Subresources; sr != nil {
8286
if sr.Scale != nil {
8387
subresources = append(subresources, "scale")
@@ -89,10 +93,6 @@ func NewResourceSyncer(
8993
}
9094
}
9195

92-
if !versionFound {
93-
return nil, fmt.Errorf("CRD %s does not define version %s requested by PublishedResource", pubRes.Spec.Resource.APIGroup, pubRes.Spec.Resource.Version)
94-
}
95-
9696
return &ResourceSyncer{
9797
log: log.With("local-gvk", localGVK, "remote-gvk", remoteGVK),
9898
localClient: localClient,

0 commit comments

Comments
 (0)