Skip to content
Open
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
19 changes: 16 additions & 3 deletions pkg/admission/pathannotation/pathannotation_admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type pathAnnotationPlugin struct {

var pathAnnotationResources = sets.New[string](
apisv1alpha2.Resource("apiexports").String(),
apisv1alpha2.Resource("apibindings").String(),
tenancyv1alpha1.Resource("workspacetypes").String(),
)

Expand Down Expand Up @@ -105,6 +106,10 @@ func (p *pathAnnotationPlugin) Admit(ctx context.Context, a admission.Attributes

logicalCluster, err := p.getLogicalCluster(clusterName, corev1alpha1.LogicalClusterName)
if err != nil {
// We skip adding for system bindings if the logical cluster is not found during creation. This is racy during workspace bootstrap.
if apierrors.IsNotFound(err) && a.GetResource().GroupResource() == apisv1alpha2.Resource("apibindings") {
return nil
}
return admission.NewForbidden(a, fmt.Errorf("cannot get this workspace: %w", err))
}
thisPath := logicalCluster.Annotations[core.LogicalClusterPathAnnotationKey]
Expand Down Expand Up @@ -136,25 +141,33 @@ func (p *pathAnnotationPlugin) Validate(ctx context.Context, a admission.Attribu
if a.GetResource().GroupResource() == corev1alpha1.Resource("logicalclusters") {
return nil
}
isAPIBinding := a.GetResource().GroupResource() == apisv1alpha2.Resource("apibindings")

u, ok := a.GetObject().(metav1.Object)
if !ok {
return fmt.Errorf("unexpected type %T", a.GetObject())
}

value, found := u.GetAnnotations()[core.LogicalClusterPathAnnotationKey]
annotations := u.GetAnnotations()
value, found := annotations[core.LogicalClusterPathAnnotationKey]
if pathAnnotationResources.Has(a.GetResource().GroupResource().String()) || found {
logicalCluster, err := p.getLogicalCluster(clusterName, corev1alpha1.LogicalClusterName)
if err != nil {
// We skip adding for system bindings if the logical cluster is not found during creation. This is racy during workspace bootstrap.
if apierrors.IsNotFound(err) && isAPIBinding {
return nil
}
return admission.NewForbidden(a, fmt.Errorf("cannot get this workspace: %w", err))
}
thisPath := logicalCluster.Annotations[core.LogicalClusterPathAnnotationKey]
if thisPath == "" {
thisPath = logicalcluster.From(logicalCluster).Path().String()
}

if value != thisPath {
return admission.NewForbidden(a, fmt.Errorf("annotation %q must match canonical path %q", core.LogicalClusterPathAnnotationKey, thisPath))
// Only validate if annotation is explicitly set (found=true) and paths don't match.
// This prevents admission of the objects without the annotation (with exception of APIBindings).
if value != thisPath && !isAPIBinding {
return admission.NewForbidden(a, fmt.Errorf("annotation for %s, %q must match canonical path %q, but got %q", a.GetName(), core.LogicalClusterPathAnnotationKey, thisPath, value))
}
}

Expand Down