Skip to content

Commit 2509acc

Browse files
committed
remove --apiexport-ref CLI flag
On-behalf-of: @SAP [email protected]
1 parent dcdfafd commit 2509acc

File tree

6 files changed

+57
-94
lines changed

6 files changed

+57
-94
lines changed

cmd/api-syncagent/kcp.go

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,10 @@ import (
3838
"sigs.k8s.io/controller-runtime/pkg/cluster"
3939
)
4040

41-
// The agent has two potentially different kcp clusters:
42-
//
43-
// endpointCluster - this is where the source of the virtual workspace URLs
44-
// live, i.e. where the APIExport/EndpointSlice.
45-
// managedCluster - this is where the APIExport and APIResourceSchemas
46-
// exist that are meant to be reconciled.
47-
//
48-
// The managedCluster always exists, the endpointCluster only if the workspace
49-
// for the virtual workspace source is different from the managed cluster.
50-
5141
// setupEndpointKcpCluster sets up a plain, non-kcp-aware ctrl-runtime Cluster object
5242
// that is solvely used to watch whichever object holds the virtual workspace URLs,
5343
// either the APIExport or the APIExportEndpointSlice.
54-
func setupEndpointKcpCluster(endpoint *syncEndpoint) (cluster.Cluster, error) {
55-
// no need for a dedicated endpoint cluster
56-
if endpoint.EndpointSlice == nil || endpoint.EndpointSlice.Cluster == endpoint.APIExport.Cluster {
57-
return nil, nil
58-
}
59-
44+
func setupEndpointKcpCluster(endpointSlice qualifiedAPIExportEndpointSlice) (cluster.Cluster, error) {
6045
scheme := runtime.NewScheme()
6146

6247
if err := kcpapisv1alpha1.AddToScheme(scheme); err != nil {
@@ -71,11 +56,11 @@ func setupEndpointKcpCluster(endpoint *syncEndpoint) (cluster.Cluster, error) {
7156
// restrict the cache's selectors accordingly so we can still make use of caching.
7257
byObject := map[ctrlruntimeclient.Object]cache.ByObject{
7358
&kcpapisv1alpha1.APIExportEndpointSlice{}: {
74-
Field: fields.SelectorFromSet(fields.Set{"metadata.name": endpoint.EndpointSlice.Name}),
59+
Field: fields.SelectorFromSet(fields.Set{"metadata.name": endpointSlice.Name}),
7560
},
7661
}
7762

78-
return cluster.New(endpoint.EndpointSlice.Config, func(o *cluster.Options) {
63+
return cluster.New(endpointSlice.Config, func(o *cluster.Options) {
7964
o.Scheme = scheme
8065
o.Cache = cache.Options{
8166
Scheme: scheme,
@@ -86,7 +71,7 @@ func setupEndpointKcpCluster(endpoint *syncEndpoint) (cluster.Cluster, error) {
8671

8772
// setupManagedKcpCluster sets up a plain, non-kcp-aware ctrl-runtime Cluster object
8873
// that is solvely used to manage the APIExport and APIResourceSchemas.
89-
func setupManagedKcpCluster(endpoint *syncEndpoint) (cluster.Cluster, error) {
74+
func setupManagedKcpCluster(apiExport qualifiedAPIExport) (cluster.Cluster, error) {
9075
scheme := runtime.NewScheme()
9176

9277
if err := kcpapisv1alpha1.AddToScheme(scheme); err != nil {
@@ -101,11 +86,11 @@ func setupManagedKcpCluster(endpoint *syncEndpoint) (cluster.Cluster, error) {
10186
// restrict the cache's selectors accordingly so we can still make use of caching.
10287
byObject := map[ctrlruntimeclient.Object]cache.ByObject{
10388
&kcpapisv1alpha1.APIExport{}: {
104-
Field: fields.SelectorFromSet(fields.Set{"metadata.name": endpoint.APIExport.Name}),
89+
Field: fields.SelectorFromSet(fields.Set{"metadata.name": apiExport.Name}),
10590
},
10691
}
10792

108-
return cluster.New(endpoint.APIExport.Config, func(o *cluster.Options) {
93+
return cluster.New(apiExport.Config, func(o *cluster.Options) {
10994
o.Scheme = scheme
11095
o.Cache = cache.Options{
11196
Scheme: scheme,
@@ -121,18 +106,18 @@ type qualifiedCluster struct {
121106
}
122107

123108
type qualifiedAPIExport struct {
124-
*kcpdevv1alpha1.APIExport
109+
*kcpapisv1alpha1.APIExport
125110
qualifiedCluster
126111
}
127112

128113
type qualifiedAPIExportEndpointSlice struct {
129-
*kcpdevv1alpha1.APIExportEndpointSlice
114+
*kcpapisv1alpha1.APIExportEndpointSlice
130115
qualifiedCluster
131116
}
132117

133118
type syncEndpoint struct {
134119
APIExport qualifiedAPIExport
135-
EndpointSlice *qualifiedAPIExportEndpointSlice
120+
EndpointSlice qualifiedAPIExportEndpointSlice
136121
}
137122

138123
// resolveSyncEndpoint takes the user provided (usually via CLI flags) APIExportEndpointSliceRef and
@@ -141,7 +126,7 @@ type syncEndpoint struct {
141126
// must point to the cluster where the APIExport lives, and vice versa for the endpoint slice;
142127
// however the endpoint slice references an APIExport in potentially another cluster, and for this
143128
// case the initialRestConfig will be rewritten accordingly).
144-
func resolveSyncEndpoint(ctx context.Context, initialRestConfig *rest.Config, endpointSliceRef string, apiExportRef string) (*syncEndpoint, error) {
129+
func resolveSyncEndpoint(ctx context.Context, initialRestConfig *rest.Config, endpointSliceRef string) (*syncEndpoint, error) {
145130
// construct temporary, uncached client
146131
scheme := runtime.NewScheme()
147132
if err := kcpcorev1alpha1.AddToScheme(scheme); err != nil {

cmd/api-syncagent/main.go

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,11 @@ func main() {
8585

8686
func run(ctx context.Context, log *zap.SugaredLogger, opts *Options) error {
8787
v := version.NewAppVersion()
88-
hello := log.With("version", v.GitVersion, "name", opts.AgentName)
89-
90-
if opts.APIExportEndpointSliceRef != "" {
91-
hello = hello.With("apiexportendpointslice", opts.APIExportEndpointSliceRef)
92-
} else {
93-
hello = hello.With("apiexport", opts.APIExportRef)
94-
}
88+
hello := log.With(
89+
"version", v.GitVersion,
90+
"name", opts.AgentName,
91+
"apiexportendpointslice", opts.APIExportEndpointSliceRef,
92+
)
9593

9694
hello.Info("Moin, I'm the kcp Sync Agent")
9795

@@ -112,22 +110,20 @@ func run(ctx context.Context, log *zap.SugaredLogger, opts *Options) error {
112110
return fmt.Errorf("kcp kubeconfig does not point to a specific workspace")
113111
}
114112

115-
// We check if the APIExport/APIExportEndpointSlice exists and extract information we need to set up our kcpCluster.
116-
endpoint, err := resolveSyncEndpoint(ctx, kcpRestConfig, opts.APIExportEndpointSliceRef, opts.APIExportRef)
113+
// We check if the APIExportEndpointSlice exists and extract information we need to set up our kcpCluster.
114+
endpoint, err := resolveSyncEndpoint(ctx, kcpRestConfig, opts.APIExportEndpointSliceRef)
117115
if err != nil {
118116
return fmt.Errorf("failed to resolve APIExport/EndpointSlice: %w", err)
119117
}
120118

121119
log.Infow("Resolved APIExport", "name", endpoint.APIExport.Name, "workspace", endpoint.APIExport.Path, "logicalcluster", endpoint.APIExport.Cluster)
122-
123-
if s := endpoint.EndpointSlice; s != nil {
124-
log.Infow("Using APIExportEndpointSlice", "name", endpoint.EndpointSlice.Name, "workspace", s.Path, "logicalcluster", s.Cluster)
125-
}
120+
log.Infow("Using APIExportEndpointSlice", "name", endpoint.EndpointSlice.Name, "workspace", endpoint.EndpointSlice.Path, "logicalcluster", endpoint.EndpointSlice.Cluster)
126121

127122
// init the "permanent" kcp cluster connections
128123

129-
// always need the managedKcpCluster
130-
managedKcpCluster, err := setupManagedKcpCluster(endpoint)
124+
// always need the managedKcpCluster, this is where we will manage the APIExport and
125+
// its resource schemas.
126+
managedKcpCluster, err := setupManagedKcpCluster(endpoint.APIExport)
131127
if err != nil {
132128
return fmt.Errorf("failed to initialize managed kcp cluster: %w", err)
133129
}
@@ -138,13 +134,16 @@ func run(ctx context.Context, log *zap.SugaredLogger, opts *Options) error {
138134
return fmt.Errorf("failed to add managed kcp cluster runnable: %w", err)
139135
}
140136

141-
// the endpoint cluster can be nil
142-
endpointKcpCluster, err := setupEndpointKcpCluster(endpoint)
143-
if err != nil {
144-
return fmt.Errorf("failed to initialize endpoint kcp cluster: %w", err)
145-
}
137+
endpointSliceCluster := managedKcpCluster
138+
139+
// If needed, start an additional cluster for the endpoint workspace, where
140+
// the EndpointSlice lives.
141+
if endpoint.EndpointSlice.Cluster != endpoint.APIExport.Cluster {
142+
endpointKcpCluster, err := setupEndpointKcpCluster(endpoint.EndpointSlice)
143+
if err != nil {
144+
return fmt.Errorf("failed to initialize endpoint kcp cluster: %w", err)
145+
}
146146

147-
if endpointKcpCluster != nil {
148147
if err := mgr.Add(endpointKcpCluster); err != nil {
149148
return fmt.Errorf("failed to add endpoint kcp cluster runnable: %w", err)
150149
}

cmd/api-syncagent/options.go

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,6 @@ type Options struct {
5454
// If not given, defaults to "<service ref>-syncagent".
5555
AgentName string
5656

57-
// APIExportRef references the APIExport within a kcp workspace that this
58-
// Sync Agent should work with by name. The APIExport has to already exist, but it must not have
59-
// any pre-existing resource schemas configured, the agent will fill them in based on
60-
// PublishedResources.
61-
//
62-
// Deprecated: Use APIExportEndpointSliceRef instead. If an APIExport is referenced, the agent
63-
// will attempt to find and use an endpoint slice of the same name.
64-
APIExportRef string
65-
6657
// APIExportEndpointSliceRef references the APIExportEndpointSlice within a kcp workspace that this
6758
// Sync Agent should work with by name. The agent will automatically manage the resource schemas
6859
// in the APIExport referenced by this endpoint slice.
@@ -96,7 +87,6 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) {
9687
flags.StringVar(&o.KcpKubeconfig, "kcp-kubeconfig", o.KcpKubeconfig, "kubeconfig file of kcp")
9788
flags.StringVar(&o.Namespace, "namespace", o.Namespace, "Kubernetes namespace the Sync Agent is running in")
9889
flags.StringVar(&o.AgentName, "agent-name", o.AgentName, "name of this Sync Agent, must not be changed after the first run, can be left blank to auto-generate a name")
99-
flags.StringVar(&o.APIExportRef, "apiexport-ref", o.APIExportRef, "name of the APIExport in kcp that this Sync Agent is powering (deprecated, use --apiexportendpointslice-ref instead)")
10090
flags.StringVar(&o.APIExportEndpointSliceRef, "apiexportendpointslice-ref", o.APIExportEndpointSliceRef, "name of the APIExportEndpointSlice in kcp that this Sync Agent is powering")
10191
flags.StringVar(&o.PublishedResourceSelectorString, "published-resource-selector", o.PublishedResourceSelectorString, "restrict this Sync Agent to only process PublishedResources matching this label selector (optional)")
10292
flags.BoolVar(&o.EnableLeaderElection, "enable-leader-election", o.EnableLeaderElection, "whether to perform leader election")
@@ -124,12 +114,8 @@ func (o *Options) Validate() error {
124114
}
125115
}
126116

127-
if len(o.APIExportRef) == 0 && len(o.APIExportEndpointSliceRef) == 0 {
128-
errs = append(errs, errors.New("either --apiexportendpointslice-ref or --apiexport-ref is required"))
129-
}
130-
131-
if len(o.APIExportRef) != 0 && len(o.APIExportEndpointSliceRef) != 0 {
132-
errs = append(errs, errors.New("--apiexportendpointslice-ref and --apiexport-ref are mutually exclusive"))
117+
if len(o.APIExportEndpointSliceRef) == 0 {
118+
errs = append(errs, errors.New("--apiexportendpointslice-ref is required"))
133119
}
134120

135121
if len(o.KcpKubeconfig) == 0 {
@@ -156,7 +142,7 @@ func (o *Options) Complete() error {
156142
errs := []error{}
157143

158144
if len(o.AgentName) == 0 {
159-
o.AgentName = o.APIExportRef + "-syncagent"
145+
o.AgentName = o.APIExportEndpointSliceRef + "-syncagent"
160146
}
161147

162148
if s := o.PublishedResourceSelectorString; len(s) > 0 {

test/e2e/sync/apiexportendpointslice_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ func TestAPIExportEndpointSliceSameCluster(t *testing.T) {
8888
t.Fatalf("Failed to create PublishedResource: %v", err)
8989
}
9090

91-
// In kcp 0.27, we have to manually create the AEES. To make this test work consistently with
92-
// 0.27 and later versions, we simply always create one.
91+
// Every APIExport we create with CreateOrganization already has an EndpointSlice,
92+
// but we create a custom one just to prove a point.
9393
kcpClusterClient := utils.GetKcpAdminClusterClient(t)
9494
orgClient := kcpClusterClient.Cluster(logicalcluster.NewPath("root").Join(orgWorkspace))
9595

@@ -110,7 +110,7 @@ func TestAPIExportEndpointSliceSameCluster(t *testing.T) {
110110
}
111111

112112
// start the agent in the background to update the APIExport with the CronTabs API;
113-
utils.RunEndpointSliceAgent(ctx, t, "bob", orgKubconfig, envtestKubeconfig, endpointSlice.Name, "")
113+
utils.RunAgent(ctx, t, "bob", orgKubconfig, envtestKubeconfig, endpointSlice.Name, "")
114114

115115
// wait until the API is available
116116
teamClusterPath := logicalcluster.NewPath("root").Join(orgWorkspace).Join("team-1")
@@ -253,7 +253,7 @@ func TestAPIExportEndpointSliceDifferentCluster(t *testing.T) {
253253
}
254254

255255
// start the agent in the background to update the APIExport with the CronTabs API
256-
utils.RunEndpointSliceAgent(ctx, t, "bob", endpointKubeconfig, envtestKubeconfig, endpointSlice.Name, "")
256+
utils.RunAgent(ctx, t, "bob", endpointKubeconfig, envtestKubeconfig, endpointSlice.Name, "")
257257

258258
// wait until the API is available
259259

test/utils/fixtures.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,24 @@ func CreateAPIExport(t *testing.T, ctx context.Context, client ctrlruntimeclient
128128
t.Fatalf("Failed to create APIExport: %v", err)
129129
}
130130

131+
// In kcp 0.27, we have to manually create the AEES. To make the tests work consistently with
132+
// 0.27 and later versions, we simply always create one.
133+
endpointSlice := &kcpapisv1alpha1.APIExportEndpointSlice{
134+
ObjectMeta: metav1.ObjectMeta{
135+
Name: name,
136+
},
137+
Spec: kcpapisv1alpha1.APIExportEndpointSliceSpec{
138+
APIExport: kcpapisv1alpha1.ExportBindingReference{
139+
Name: name,
140+
},
141+
},
142+
}
143+
144+
t.Logf("Creating APIExportEndpointSlice %q…", endpointSlice.Name)
145+
if err := client.Create(ctx, endpointSlice); err != nil {
146+
t.Fatalf("Failed to create APIExportEndpointSlice: %v", err)
147+
}
148+
131149
// grant permissions to access/manage the APIExport
132150
if rbacSubject != nil {
133151
clusterRoleName := "api-syncagent"

test/utils/process.go

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,38 +68,13 @@ func uniqueLogfile(t *testing.T, basename string) string {
6868
return fmt.Sprintf("%s_%02d.log", testName, counter)
6969
}
7070

71-
func RunEndpointSliceAgent(
72-
ctx context.Context,
73-
t *testing.T,
74-
name string,
75-
kcpKubeconfig string,
76-
localKubeconfig string,
77-
apiExportEndpointSlice string,
78-
labelSelector string,
79-
) context.CancelFunc {
80-
return runAgent(ctx, t, name, kcpKubeconfig, localKubeconfig, "--apiexportendpointslice-ref", apiExportEndpointSlice, labelSelector)
81-
}
82-
8371
func RunAgent(
8472
ctx context.Context,
8573
t *testing.T,
8674
name string,
8775
kcpKubeconfig string,
8876
localKubeconfig string,
89-
apiExport string,
90-
labelSelector string,
91-
) context.CancelFunc {
92-
return runAgent(ctx, t, name, kcpKubeconfig, localKubeconfig, "--apiexport-ref", apiExport, labelSelector)
93-
}
94-
95-
func runAgent(
96-
ctx context.Context,
97-
t *testing.T,
98-
name string,
99-
kcpKubeconfig string,
100-
localKubeconfig string,
101-
refFlag string,
102-
refValue string,
77+
apiExportEndpointSlice string,
10378
labelSelector string,
10479
) context.CancelFunc {
10580
t.Helper()
@@ -108,7 +83,7 @@ func runAgent(
10883

10984
args := []string{
11085
"--agent-name", name,
111-
refFlag, refValue,
86+
"--apiexportendpointslice-ref", apiExportEndpointSlice,
11287
"--enable-leader-election=false",
11388
"--kubeconfig", localKubeconfig,
11489
"--kcp-kubeconfig", kcpKubeconfig,

0 commit comments

Comments
 (0)