@@ -17,8 +17,8 @@ limitations under the License.
1717package apiexport
1818
1919import (
20- "cmp"
2120 "slices"
21+ "strings"
2222
2323 "github.com/kcp-dev/api-syncagent/internal/resources/reconciling"
2424 syncagentv1alpha1 "github.com/kcp-dev/api-syncagent/sdk/apis/syncagent/v1alpha1"
@@ -34,16 +34,13 @@ import (
3434func (r * Reconciler ) createAPIExportReconciler (availableResourceSchemas sets.Set [string ], claimedResourceKinds sets.Set [string ], agentName string , apiExportName string ) reconciling.NamedAPIExportReconcilerFactory {
3535 return func () (string , reconciling.APIExportReconciler ) {
3636 return apiExportName , func (existing * kcpdevv1alpha1.APIExport ) (* kcpdevv1alpha1.APIExport , error ) {
37- known := sets .New (existing .Spec .LatestResourceSchemas ... )
38-
3937 if existing .Annotations == nil {
4038 existing .Annotations = map [string ]string {}
4139 }
4240 existing .Annotations [syncagentv1alpha1 .AgentNameAnnotation ] = agentName
4341
44- // we only ever add new schemas
45- result := known .Union (availableResourceSchemas )
46- existing .Spec .LatestResourceSchemas = sets .List (result )
42+ // combine existing schemas with new ones
43+ existing .Spec .LatestResourceSchemas = mergeResourceSchemas (existing .Spec .LatestResourceSchemas , availableResourceSchemas )
4744
4845 // To allow admins to configure additional permission claims, sometimes
4946 // useful for debugging, we do not override the permission claims, but
@@ -73,11 +70,11 @@ func (r *Reconciler) createAPIExportReconciler(availableResourceSchemas sets.Set
7370 // prevent reconcile loops by ensuring a stable order
7471 slices .SortFunc (existing .Spec .PermissionClaims , func (a , b kcpdevv1alpha1.PermissionClaim ) int {
7572 if a .Group != b .Group {
76- return cmp .Compare (a .Group , b .Group )
73+ return strings .Compare (a .Group , b .Group )
7774 }
7875
7976 if a .Resource != b .Resource {
80- return cmp .Compare (a .Resource , b .Resource )
77+ return strings .Compare (a .Resource , b .Resource )
8178 }
8279
8380 return 0
@@ -87,3 +84,38 @@ func (r *Reconciler) createAPIExportReconciler(availableResourceSchemas sets.Set
8784 }
8885 }
8986}
87+
88+ func mergeResourceSchemas (existing []string , configured sets.Set [string ]) []string {
89+ var result []string
90+
91+ // first we copy all ARS that are coming from the PublishedResources
92+ knownResources := sets .New [string ]()
93+ for _ , schema := range configured .UnsortedList () {
94+ result = append (result , schema )
95+ knownResources .Insert (parseResourceGroup (schema ))
96+ }
97+
98+ // Now we include all other existing ARS that use unknown resources;
99+ // this both allows an APIExport to contain "unmanaged" ARS, and also
100+ // will purposefully leave behind ARS for deleted PublishedResources,
101+ // allowing cleanup to take place outside of the agent's control.
102+ for _ , schema := range existing {
103+ if ! knownResources .Has (parseResourceGroup (schema )) {
104+ result = append (result , schema )
105+ }
106+ }
107+
108+ // for stability and beauty, sort the schemas
109+ slices .SortFunc (result , func (a , b string ) int {
110+ return strings .Compare (parseResourceGroup (a ), parseResourceGroup (b ))
111+ })
112+
113+ return result
114+ }
115+
116+ func parseResourceGroup (schema string ) string {
117+ // <version>.<resource>.<group>
118+ parts := strings .SplitN (schema , "." , 2 )
119+
120+ return parts [1 ]
121+ }
0 commit comments