Skip to content
23 changes: 23 additions & 0 deletions config/crds/core.kcp.io_logicalclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ spec:
- resource
- uid
type: object
terminators:
description: |-
Terminators are set on creation by the system and copied to status when
termination starts.
items:
description: |-
LogicalClusterTerminator is a unique string corresponding to a logical cluster
terminator controller.
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(:[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(:[a-z0-9][a-z0-9]([-a-z0-9]*[a-z0-9])?))|(system:.+)$
type: string
type: array
type: object
status:
default: {}
Expand Down Expand Up @@ -197,6 +208,18 @@ spec:
- Ready
- Unavailable
type: string
terminators:
description: |-
Terminators are set on creation by the system and must be cleared
by a controller before the logical cluster can be deleted. The LogicalCluster object
will stay in the phase "Deleting" until all terminator are cleared.
items:
description: |-
LogicalClusterTerminator is a unique string corresponding to a logical cluster
terminator controller.
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(:[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(:[a-z0-9][a-z0-9]([-a-z0-9]*[a-z0-9])?))|(system:.+)$
type: string
type: array
type: object
type: object
served: true
Expand Down
11 changes: 11 additions & 0 deletions config/crds/tenancy.kcp.io_workspaces.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,17 @@ spec:
- Ready
- Unavailable
type: string
terminators:
description: |-
terminators must be cleared by a controller before the workspace is being
deleted.
items:
description: |-
LogicalClusterTerminator is a unique string corresponding to a logical cluster
terminator controller.
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(:[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(:[a-z0-9][a-z0-9]([-a-z0-9]*[a-z0-9])?))|(system:.+)$
type: string
type: array
type: object
required:
- spec
Expand Down
12 changes: 12 additions & 0 deletions config/crds/tenancy.kcp.io_workspacetypes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,18 @@ spec:
minItems: 1
type: array
type: object
terminator:
description: |-
Terminator determines if this WorkspaceType has an associated terminating
controller. These controllers are used to add functionality to a Workspace;
all controllers must finish their work before the Workspace is being deleted.

One terminating controller is supported per WorkspaceType; the identifier
for this terminator will be a colon-delimited string using the workspace in which
the WorkspaceType is defined, and the type's name. For example, if a
WorkspaceType `example` is created in the `root:org` workspace, the implicit
terminator name is `root:org:example`.
type: boolean
type: object
status:
description: WorkspaceTypeStatus defines the observed state of WorkspaceType.
Expand Down
4 changes: 2 additions & 2 deletions config/root-phase0/apiexport-tenancy.kcp.io.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ spec:
crd: {}
- group: tenancy.kcp.io
name: workspaces
schema: v250421-25d98218b.workspaces.tenancy.kcp.io
schema: v251015-1d163d0e5.workspaces.tenancy.kcp.io
storage:
crd: {}
- group: tenancy.kcp.io
name: workspacetypes
schema: v250806-4c99c4583.workspacetypes.tenancy.kcp.io
schema: v251015-1d163d0e5.workspacetypes.tenancy.kcp.io
storage:
crd: {}
status: {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apis.kcp.io/v1alpha1
kind: APIResourceSchema
metadata:
creationTimestamp: null
name: v241020-fce06d31d.logicalclusters.core.kcp.io
name: v251016-6e24e0d49.logicalclusters.core.kcp.io
spec:
group: core.kcp.io
names:
Expand Down Expand Up @@ -117,6 +117,17 @@ spec:
- resource
- uid
type: object
terminators:
description: |-
Terminators are set on creation by the system and copied to status when
termination starts.
items:
description: |-
LogicalClusterTerminator is a unique string corresponding to a logical cluster
terminator controller.
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(:[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(:[a-z0-9][a-z0-9]([-a-z0-9]*[a-z0-9])?))|(system:.+)$
type: string
type: array
type: object
status:
default: {}
Expand Down Expand Up @@ -195,6 +206,18 @@ spec:
- Ready
- Unavailable
type: string
terminators:
description: |-
Terminators are set on creation by the system and must be cleared
by a controller before the logical cluster can be deleted. The LogicalCluster object
will stay in the phase "Deleting" until all terminator are cleared.
items:
description: |-
LogicalClusterTerminator is a unique string corresponding to a logical cluster
terminator controller.
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(:[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(:[a-z0-9][a-z0-9]([-a-z0-9]*[a-z0-9])?))|(system:.+)$
type: string
type: array
type: object
type: object
served: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apis.kcp.io/v1alpha1
kind: APIResourceSchema
metadata:
creationTimestamp: null
name: v250421-25d98218b.workspaces.tenancy.kcp.io
name: v251015-1d163d0e5.workspaces.tenancy.kcp.io
spec:
group: tenancy.kcp.io
names:
Expand Down Expand Up @@ -297,6 +297,17 @@ spec:
- Ready
- Unavailable
type: string
terminators:
description: |-
terminators must be cleared by a controller before the workspace is being
deleted.
items:
description: |-
LogicalClusterTerminator is a unique string corresponding to a logical cluster
terminator controller.
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(:[a-z0-9]([-a-z0-9]*[a-z0-9])?)*(:[a-z0-9][a-z0-9]([-a-z0-9]*[a-z0-9])?))|(system:.+)$
type: string
type: array
type: object
required:
- spec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apis.kcp.io/v1alpha1
kind: APIResourceSchema
metadata:
creationTimestamp: null
name: v250806-4c99c4583.workspacetypes.tenancy.kcp.io
name: v251015-1d163d0e5.workspacetypes.tenancy.kcp.io
spec:
group: tenancy.kcp.io
names:
Expand Down Expand Up @@ -247,6 +247,18 @@ spec:
minItems: 1
type: array
type: object
terminator:
description: |-
Terminator determines if this WorkspaceType has an associated terminating
controller. These controllers are used to add functionality to a Workspace;
all controllers must finish their work before the Workspace is being deleted.

One terminating controller is supported per WorkspaceType; the identifier
for this terminator will be a colon-delimited string using the workspace in which
the WorkspaceType is defined, and the type's name. For example, if a
WorkspaceType `example` is created in the `root:org` workspace, the implicit
terminator name is `root:org:example`.
type: boolean
type: object
status:
description: WorkspaceTypeStatus defines the observed state of WorkspaceType.
Expand Down
2 changes: 2 additions & 0 deletions pkg/admission/logicalcluster/admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ func (o *plugin) Admit(ctx context.Context, a admission.Attributes, _ admission.

logicalCluster.Status.Initializers = logicalCluster.Spec.Initializers

logicalCluster.Status.Terminators = logicalCluster.Spec.Terminators

return updateUnstructured(u, logicalCluster)
}

Expand Down
52 changes: 52 additions & 0 deletions pkg/openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ type reconciler interface {
}

func (c *Controller) reconcile(ctx context.Context, logicalCluster *corev1alpha1.LogicalCluster) (bool, error) {
// reconcilers which modify Status should be last
// reconcilers which modify ObjectMeta, need to return reconcileStatusStopAndRequeue on change
reconcilers := []reconciler{
&metaDataReconciler{},
&terminatorReconciler{},
&phaseReconciler{},
&urlReconciler{shardExternalURL: c.shardExternalURL},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

corev1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1"
"github.com/kcp-dev/kcp/sdk/apis/tenancy/initialization"
"github.com/kcp-dev/kcp/sdk/apis/tenancy/termination"
tenancyv1alpha1 "github.com/kcp-dev/kcp/sdk/apis/tenancy/v1alpha1"
)

Expand All @@ -39,7 +40,7 @@ func (r *metaDataReconciler) reconcile(ctx context.Context, logicalCluster *core

expected := string(logicalCluster.Status.Phase)
if !logicalCluster.DeletionTimestamp.IsZero() {
expected = "Deleting"
expected = string(corev1alpha1.LogicalClusterPhaseDeleting)
}
if got := logicalCluster.Labels[tenancyv1alpha1.WorkspacePhaseLabel]; got != expected {
if logicalCluster.Labels == nil {
Expand All @@ -49,6 +50,7 @@ func (r *metaDataReconciler) reconcile(ctx context.Context, logicalCluster *core
changed = true
}

// add initializers from the status as hashed labels
initializerKeys := sets.New[string]()
for _, initializer := range logicalCluster.Status.Initializers {
key, value := initialization.InitializerToLabel(initializer)
Expand All @@ -62,13 +64,36 @@ func (r *metaDataReconciler) reconcile(ctx context.Context, logicalCluster *core
}
}

// add terminators from the status as hashed labels
terminatorKeys := sets.New[string]()
for _, terminator := range logicalCluster.Status.Terminators {
key, value := termination.TerminatorToLabel(terminator)
terminatorKeys.Insert(key)
if got, expected := logicalCluster.Labels[key], value; got != expected {
if logicalCluster.Labels == nil {
logicalCluster.Labels = map[string]string{}
}
logicalCluster.Labels[key] = value
changed = true
}
}

// remove any initializers/terminators from labels, which have been
// removed in the status
for key := range logicalCluster.Labels {
if strings.HasPrefix(key, tenancyv1alpha1.WorkspaceInitializerLabelPrefix) {
if !initializerKeys.Has(key) {
delete(logicalCluster.Labels, key)
changed = true
}
}

if strings.HasPrefix(key, tenancyv1alpha1.WorkspaceTerminatorLabelPrefix) {
if !terminatorKeys.Has(key) {
delete(logicalCluster.Labels, key)
changed = true
}
}
}

if logicalCluster.Status.Phase == corev1alpha1.LogicalClusterPhaseReady {
Expand Down
Loading