Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion internal/controllers/provider/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,12 @@ func (r *ProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (r
}
}

// patch the status
// Patch the status - but exclude field status.resources as it is set by the provider.
if copyErr := CopyNestedSlice(providerOrig, provider, "status", "resources"); copyErr != nil {
err = errors.Join(err, copyErr)
return res, err
}

updateErr := r.PlatformClient.Status().Patch(ctx, provider, client.MergeFrom(providerOrig))
err = errors.Join(err, updateErr)
return res, err
Expand Down Expand Up @@ -234,3 +239,16 @@ func (r *ProviderReconciler) removeFinalizer(ctx context.Context, provider *unst
}
return nil
}

func CopyNestedSlice(source, target *unstructured.Unstructured, fieldPath ...string) error {
value, found, err := unstructured.NestedSlice(source.Object, fieldPath...)
if err != nil {
return fmt.Errorf("failed to get nested slice: %w", err)
}
if found {
if err := unstructured.SetNestedSlice(target.Object, value, fieldPath...); err != nil {
return fmt.Errorf("failed to set nested slice: %w", err)
}
}
return nil
}
28 changes: 28 additions & 0 deletions internal/controllers/provider/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,32 @@ var _ = Describe("Deployment Controller", func() {
Expect(provider2.Object).To(Equal(provider.Object))
})
})

Context("Copy field between unstructured", func() {

sliceCopy := []any{"c", "o", "p", "y"}
sliceKeep := []any{"k", "e", "e", "p"}
fieldPathCopy := []string{"status", "resourcesCopy"}
fieldPathKeep := []string{"status", "resourcesKeep"}

It("should copy a nested slice and keep another field", func() {
u1 := &unstructured.Unstructured{Object: map[string]any{}}
Expect(unstructured.SetNestedSlice(u1.Object, sliceCopy, fieldPathCopy...)).To(Succeed())

u2 := &unstructured.Unstructured{Object: map[string]any{}}
Expect(unstructured.SetNestedSlice(u2.Object, sliceKeep, fieldPathKeep...)).To(Succeed())

Expect(CopyNestedSlice(u1, u2, fieldPathCopy...)).To(Succeed())

value, found, err := unstructured.NestedSlice(u2.Object, fieldPathCopy...)
Expect(err).NotTo(HaveOccurred())
Expect(found).To(BeTrue())
Expect(value).To(Equal(sliceCopy))

value, found, err = unstructured.NestedSlice(u2.Object, fieldPathKeep...)
Expect(err).NotTo(HaveOccurred())
Expect(found).To(BeTrue())
Expect(value).To(Equal(sliceKeep))
})
})
})
41 changes: 41 additions & 0 deletions lib/utils/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package utils

import (
"context"
"fmt"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/openmcp-project/openmcp-operator/api/provider/v1alpha1"
)

// GetServiceProviderResource retrieves the ServiceProvider resource with the given name using the provided platform client.
func GetServiceProviderResource(ctx context.Context, platformClient client.Client, providerName string) (*v1alpha1.ServiceProvider, error) {
serviceProvider := &v1alpha1.ServiceProvider{
ObjectMeta: metav1.ObjectMeta{
Name: providerName,
},
}
if err := platformClient.Get(ctx, client.ObjectKeyFromObject(serviceProvider), serviceProvider); err != nil {
return nil, fmt.Errorf("failed to get service provider resource %s: %w", providerName, err)
}
return serviceProvider, nil
}

// RegisterGVKsAtServiceProvider updates the status.resources field of the ServiceProvider resource with the provided GroupVersionKinds.
// This can be used by service providers, for example in their init job, to register the kinds of resources they manage.
func RegisterGVKsAtServiceProvider(ctx context.Context, platformClient client.Client, providerName string, gvks ...metav1.GroupVersionKind) error {
providerResource, err := GetServiceProviderResource(ctx, platformClient, providerName)
if err != nil {
return err
}

providerResourceOld := providerResource.DeepCopy()
providerResource.Status.Resources = gvks
if err := platformClient.Status().Patch(ctx, providerResource, client.MergeFrom(providerResourceOld)); err != nil {
return fmt.Errorf("failed to patch platform service provider status: %w", err)
}

return nil
}