organization

package
v0.2.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package organization gives every new organization the same bootstrap lifecycle. The User reconciler requests a personal organization and mirrors its references; the Organization reconciler provisions both personal and additional orgs, their default workspace, API binding, administrator access, MCP server, and index. Access handoff and completion are durable and prevent subsequent grant replay or workspace recreation. Delayed identity access repair follows current memberships separately from organization provisioning.

Index

Constants

View Source
const AnnotationCatalogEntryCreationMigrated = "tenants.railgrid.ai/catalog-entry-creation-migrated"

AnnotationCatalogEntryCreationMigrated marks an Organization the one-time catalogEntryCreation backfill has visited. Its absence is what identifies an Organization that predates the admin default.

Variables

This section is empty.

Functions

func BackfillCatalogEntryCreation

func BackfillCatalogEntryCreation(ctx context.Context, reader client.Reader, writer client.Client) (int, error)

BackfillCatalogEntryCreation pins the pre-flip behaviour onto every Organization created before spec.catalogEntryCreation defaulted to admin.

The hub used to read an empty field as "members"; it now reads it as "admin". Organizations that never set the field relied on the old reading, so each one without the migrated annotation gets an explicit "members" written — an Organization that already carries a value keeps it — and the annotation stamped, after which the backfill never touches it again. New Organizations are created with an explicit value and are simply stamped on first sight.

reader supplies the Organization list and MUST NOT be cache-backed: an empty list from a cold cache is indistinguishable from an empty cluster, and this backfill treats "nothing to do" as final. writer applies the patches.

Returns the number of Organizations updated. Errors are returned after the first failed write; the caller retries, and every write is idempotent.

func NewManager

func NewManager(cfg *rest.Config, scheme *runtime.Scheme) (manager.Manager, error)

NewManager constructs a controller-runtime manager bound to a single workspace's rest.Config (typically the root:railgrid:users workspace returned by Bootstrapper.UsersConfig). The hub server calls this and runs the manager in a goroutine alongside the multicluster managers.

func SetupWithManager

func SetupWithManager(mgr manager.Manager, provisioner WorkspaceProvisioner) error

SetupWithManager registers a User reference controller and a single Organization lifecycle controller. Organization events refresh their personal owner's references; creator User events resume pending organization bootstrap. All provisioning is scoped by the Organization key, for both organization kinds.

Types

type Reconciler

type Reconciler struct {
	// contains filtered or unexported fields
}

Reconciler requests personal organizations and maintains User references. The Organization lifecycle controller embeds its shared clients and helpers.

func (*Reconciler) Reconcile

func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile requests a personal Organization and mirrors its workspace references. Provisioning belongs exclusively to organizationReconciler. Identity backfill handles delayed first-login identities using current membership authority.

type WorkspaceProvisioner

type WorkspaceProvisioner interface {
	// EnsureOrgWorkspace materializes the kcp Workspace at
	// root:railgrid:tenants:{orgUUID}. Idempotent (per O-11).
	EnsureOrgWorkspace(ctx context.Context, orgUUID string) error

	// EnsureOrgMembership creates an org-scope Membership CR inside the
	// Organization workspace granting userName the given role.
	// Idempotent.
	EnsureOrgMembership(ctx context.Context, orgUUID, userName, role string) error

	// ListOrgMembershipRoles reads current organization membership authority.
	// Initial workspace access includes every current org administrator.
	ListOrgMembershipRoles(ctx context.Context, orgUUID string) (map[string]string, error)

	// EnsureChildWorkspace materializes the kcp Workspace at
	// root:railgrid:tenants:{orgUUID}:{wsUUID} of type `workspace`. Used to
	// create the initial team Workspace inside either organization kind.
	// Idempotent (per O-11).
	EnsureChildWorkspace(ctx context.Context, orgUUID, wsUUID string) error

	// EnsureChildWorkspaceDisplayName stamps the display-name
	// annotation on the child Workspace when none is set yet, so the
	// default workspace surfaces under a human-readable name instead
	// of its UUID. Never overwrites an existing name — a user rename
	// must survive reconciles. Idempotent.
	EnsureChildWorkspaceDisplayName(ctx context.Context, orgUUID, wsUUID, displayName string) error

	// EnsureChildWorkspaceRailgridBinding materializes an APIBinding to
	// root:railgrid:providers.core.railgrid.ai inside the child team
	// Workspace, with the permission claims railgrid controllers need.
	// This is what makes Edge / MCPServer / Placement / VirtualWorkload
	// usable inside the user's default Workspace. Idempotent.
	EnsureChildWorkspaceRailgridBinding(ctx context.Context, orgUUID, wsUUID string) error

	// EnsureChildWorkspaceAdmin grants cluster-admin to the User in
	// the child team Workspace via a ClusterRoleBinding for the User's
	// rbacIdentity. Idempotent.
	EnsureChildWorkspaceAdmin(ctx context.Context, orgUUID, wsUUID, rbacIdentity string) error

	// ListChildTeamWorkspaces lists the Org's team workspaces (no
	// infrastructure children). Used by the RBAC backfill to bind an
	// org-scope admin into every child workspace (O-15).
	ListChildTeamWorkspaces(ctx context.Context, orgUUID string) ([]string, error)

	// EnsureChildWorkspaceDefaultMCPServer seeds the "default"
	// MCPServer CR inside the child team Workspace so users have a
	// working MCP endpoint out of the box. Idempotent.
	EnsureChildWorkspaceDefaultMCPServer(ctx context.Context, orgUUID, wsUUID string) error

	// GetChildWorkspaceClusterName returns the kcp logical-cluster
	// short hash for the child team Workspace. Used by User reconciliation to patch
	// User.spec.DefaultCluster with the hash form (which kubectl /
	// /clusters/{hash} address by) rather than the full path.
	GetChildWorkspaceClusterName(ctx context.Context, orgUUID, wsUUID string) (string, error)
}

WorkspaceProvisioner is the slice of the kcp Bootstrapper that this controller needs to materialize Organization workspaces, the default child Workspace inside each new Org, and membership/access setup. Pulled out as an interface so unit tests can use a fake (see controller_test.go) without standing up an embedded kcp.

Implemented by *pkg/hub/kcp.Bootstrapper.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL