Skip to content

Support virtual workspace URL in --config-workspace for self-service provider initialization #18

@ifdotpy

Description

@ifdotpy

Problem

init-agent's --config-workspace flag only accepts a logical cluster path (e.g., root:init-agent). Internally, RetargetRestConfig() appends /clusters/<path> to the base KCP URL. This means init-agent cannot point to an APIExport virtual workspace URL, which uses a different URL pattern (/services/apiexport/<path>/<export-name>).

This limits init-agent to watching a single shared config workspace. Providers that want to register their own InitTarget + InitTemplate must have write access to that shared workspace — breaking the permission model in multi-provider setups.

Proposed Solution

Allow --config-workspace to accept either:

  • A logical cluster path (existing behavior, unchanged): root:init-agent/clusters/root:init-agent
  • A direct URL path (new): /services/apiexport/root:platform-mesh-system/initialization.kcp.io → used as-is

Code change (cmd/init-agent/main.go, ~10 lines)

// Current (line 148):
cfg = kcp.RetargetRestConfig(cfg, logicalcluster.Name(opts.ConfigWorkspace))

// Proposed:
if strings.HasPrefix(opts.ConfigWorkspace, "/") {
    // Direct URL path (e.g., virtual workspace)
    stripped := kcp.StripCluster(cfg)
    stripped.Host = strings.TrimRight(stripped.Host, "/") + opts.ConfigWorkspace
    cfg = stripped
} else {
    // Logical cluster path (existing behavior, unchanged)
    cfg = kcp.RetargetRestConfig(cfg, logicalcluster.Name(opts.ConfigWorkspace))
}

Fully backward compatible — existing --config-workspace=root:init-agent continues to work.

Why it works

The Manager and ClusterClient use different base URLs:

  • Manager → config workspace URL (watches InitTarget/InitTemplate)
  • ClusterClient → base KCP URL stripped of any cluster path (fetches WorkspaceTypes, InitTemplates from actual workspaces)

When init-agent finds an InitTarget in the virtual workspace, ClusterNameFromObject(target) returns the provider's logical cluster ID. The ClusterClient then fetches the InitTemplate directly from the provider workspace via /clusters/<provider-cluster-id>. This is independent of the config workspace URL.

Use Case: Self-Service Provider Initialization

With this change, a platform can expose initialization.kcp.io CRDs via an APIExport. Provider workspaces bind to it and create InitTarget + InitTemplate in their own workspace. init-agent watches the APIExport's virtual workspace, which aggregates templates from all bound provider workspaces.

Platform (one-time setup):
  1. APIExport "initialization.kcp.io" exposing InitTarget + InitTemplate CRDs
  2. init-agent with --config-workspace=/services/apiexport/.../initialization.kcp.io

Provider (self-service, in own workspace):
  1. APIBinding to initialization.kcp.io
  2. Create InitTarget + InitTemplate
  3. init-agent discovers them via virtual workspace aggregation

No shared config workspace, no cross-workspace write access needed.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions