Skip to content

WIP - Add support for Go template expressions in PublishedResources #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
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
8 changes: 7 additions & 1 deletion deploy/crd/kcp.io/syncagent.kcp.io_publishedresources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ spec:
description: |-
Reference points to a field inside the main object. This reference is
evaluated on both source and destination sides to find the related object.

Deprecated: Use Go templates instead.
properties:
path:
description: |-
Expand Down Expand Up @@ -553,6 +555,8 @@ spec:
description: |-
Reference points to a field inside the main object. This reference is
evaluated on both source and destination sides to find the related object.

Deprecated: Use Go templates instead.
properties:
path:
description: |-
Expand Down Expand Up @@ -665,7 +669,9 @@ spec:
type: object
type: object
origin:
description: '"service" or "kcp"'
enum:
- service
- kcp
type: string
required:
- identifier
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/kcp-dev/api-syncagent

go 1.23.0
go 1.24.0

replace github.com/kcp-dev/api-syncagent/sdk => ./sdk

Expand Down
69 changes: 0 additions & 69 deletions internal/projection/naming.go

This file was deleted.

5 changes: 2 additions & 3 deletions internal/sync/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package sync

import (
"context"
"testing"

"github.com/kcp-dev/logicalcluster/v3"
Expand All @@ -27,9 +26,9 @@ import (

func TestNewContext(t *testing.T) {
clusterName := logicalcluster.Name("foo")
ctx := kontext.WithCluster(context.Background(), clusterName)
ctx := kontext.WithCluster(t.Context(), clusterName)

combinedCtx := NewContext(context.Background(), ctx)
combinedCtx := NewContext(t.Context(), ctx)

if combinedCtx.clusterName != clusterName {
t.Fatalf("Expected function to recognize the cluster name in the context, but got %q", combinedCtx.clusterName)
Expand Down
13 changes: 10 additions & 3 deletions internal/sync/object_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client"
)

type objectCreatorFunc func(source *unstructured.Unstructured) *unstructured.Unstructured
type objectCreatorFunc func(source *unstructured.Unstructured) (*unstructured.Unstructured, error)

type objectSyncer struct {
// When set, the syncer will create a label on the destination object that contains
Expand Down Expand Up @@ -134,7 +134,11 @@ func (s *objectSyncer) applyMutations(source, dest syncSide) (syncSide, syncSide
// the mutated names available.
destObject := dest.object
if destObject == nil {
destObject = s.destCreator(source.object)
var err error
destObject, err = s.destCreator(source.object)
if err != nil {
return source, dest, fmt.Errorf("failed to create destination object: %w", err)
}
}

sourceObj, err := s.mutator.MutateSpec(source.object.DeepCopy(), destObject)
Expand Down Expand Up @@ -287,7 +291,10 @@ func (s *objectSyncer) syncObjectStatus(log *zap.SugaredLogger, source, dest syn

func (s *objectSyncer) ensureDestinationObject(log *zap.SugaredLogger, source, dest syncSide) error {
// create a copy of the source with GVK projected and renaming rules applied
destObj := s.destCreator(source.object)
destObj, err := s.destCreator(source.object)
if err != nil {
return fmt.Errorf("failed to create destination object: %w", err)
}

// make sure the target namespace on the destination cluster exists
if err := s.ensureNamespace(dest.ctx, log, dest.client, destObj.GetNamespace()); err != nil {
Expand Down
3 changes: 1 addition & 2 deletions internal/sync/state_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package sync

import (
"context"
"testing"

dummyv1alpha1 "github.com/kcp-dev/api-syncagent/internal/sync/apis/dummy/v1alpha1"
Expand All @@ -37,7 +36,7 @@ func TestStateStoreBasics(t *testing.T) {
}, withKind("RemoteThing"))

serviceClusterClient := buildFakeClient()
ctx := context.Background()
ctx := t.Context()
stateNamespace := "kcp-system"

primaryObjectSide := syncSide{
Expand Down
14 changes: 9 additions & 5 deletions internal/sync/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/kcp-dev/api-syncagent/internal/mutation"
"github.com/kcp-dev/api-syncagent/internal/projection"
"github.com/kcp-dev/api-syncagent/internal/sync/templating"
syncagentv1alpha1 "github.com/kcp-dev/api-syncagent/sdk/apis/syncagent/v1alpha1"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
Expand Down Expand Up @@ -152,7 +153,7 @@ func (s *ResourceSyncer) Process(ctx Context, remoteObj *unstructured.Unstructur
agentName: s.agentName,
subresources: s.subresources,
// use the projection and renaming rules configured in the PublishedResource
destCreator: s.createLocalObjectCreator(ctx),
destCreator: s.newLocalObjectCreator(ctx),
// for the main resource, status subresource handling is enabled (this
// means _allowing_ status back-syncing, it still depends on whether the
// status subresource even exists whether an update happens)
Expand Down Expand Up @@ -214,8 +215,8 @@ func (s *ResourceSyncer) findLocalObject(ctx Context, remoteObj *unstructured.Un
}
}

func (s *ResourceSyncer) createLocalObjectCreator(ctx Context) objectCreatorFunc {
return func(remoteObj *unstructured.Unstructured) *unstructured.Unstructured {
func (s *ResourceSyncer) newLocalObjectCreator(ctx Context) objectCreatorFunc {
return func(remoteObj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
// map from the remote API into the actual, local API group
destObj := remoteObj.DeepCopy()
destObj.SetGroupVersionKind(s.destDummy.GroupVersionKind())
Expand All @@ -224,7 +225,10 @@ func (s *ResourceSyncer) createLocalObjectCreator(ctx Context) objectCreatorFunc
destScope := syncagentv1alpha1.ResourceScope(s.localCRD.Spec.Scope)

// map namespace/name
mappedName := projection.GenerateLocalObjectName(s.pubRes, remoteObj, ctx.clusterName)
mappedName, err := templating.GenerateLocalObjectName(s.pubRes, remoteObj, ctx.clusterName, ctx.workspacePath)
if err != nil {
return nil, fmt.Errorf("failed to generate local object name: %w", err)
}

switch destScope {
case syncagentv1alpha1.ClusterScoped:
Expand All @@ -236,6 +240,6 @@ func (s *ResourceSyncer) createLocalObjectCreator(ctx Context) objectCreatorFunc
destObj.SetName(mappedName.Name)
}

return destObj
return destObj, nil
}
}
Loading