Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9d887cd
fix(controller): decode old object for delete requests
oliverbaehler Dec 10, 2025
221e0e8
chore: modernize golang
oliverbaehler Dec 10, 2025
052660e
chore: modernize golang
oliverbaehler Dec 10, 2025
7c418d0
chore: modernize golang
oliverbaehler Dec 10, 2025
7db5048
Merge branch 'main' of github.com:projectcapsule/capsule
oliverbaehler Dec 11, 2025
98f9add
Merge branch 'main' of github.com:projectcapsule/capsule
oliverbaehler Dec 15, 2025
f448bdf
Merge branch 'main' of github.com:projectcapsule/capsule
oliverbaehler Dec 19, 2025
033e098
Merge branch 'main' of github.com:projectcapsule/capsule
oliverbaehler Dec 19, 2025
21cd932
Merge branch 'main' of github.com:projectcapsule/capsule
oliverbaehler Dec 25, 2025
1e28f1b
Merge branch 'main' of github.com:projectcapsule/capsule
oliverbaehler Jan 5, 2026
668c847
fix(config): remove usergroups default
oliverbaehler Jan 6, 2026
5b05b17
fix(config): remove usergroups default
oliverbaehler Jan 6, 2026
2327f9c
sec(ghsa-2ww6-hf35-mfjm): intercept namespace subresource
oliverbaehler Jan 22, 2026
1cc70ee
feat(api): add rulestatus api
oliverbaehler Jan 22, 2026
3c17c8f
chore: conflicts
oliverbaehler Jan 22, 2026
3203d4d
chore: conflicts
oliverbaehler Jan 22, 2026
b41cbdf
chore: conflicts
oliverbaehler Jan 22, 2026
b926322
chore: conflicts
oliverbaehler Jan 22, 2026
98c1732
chore: conflicts
oliverbaehler Jan 22, 2026
7747ade
chore: conflicts
oliverbaehler Jan 22, 2026
44e27bc
chore: conflicts
oliverbaehler Jan 22, 2026
d771a15
chore: conflicts
oliverbaehler Jan 22, 2026
17544df
chore: conflicts
oliverbaehler Jan 23, 2026
3cce446
chore: conflicts
oliverbaehler Jan 23, 2026
a671091
chore: conflicts
oliverbaehler Jan 23, 2026
b622023
chore: conflicts
oliverbaehler Jan 23, 2026
174d884
feat(api): add rulestatus api
oliverbaehler Jan 27, 2026
f41a3f3
feat(api): add rulestatus api
oliverbaehler Jan 27, 2026
548803e
feat(api): add rulestatus api
oliverbaehler Jan 27, 2026
50c04c2
feat(api): add rulestatus api
oliverbaehler Jan 27, 2026
820f6b5
feat(api): add rulestatus api
oliverbaehler Jan 27, 2026
45531a5
feat(api): add rulestatus api
oliverbaehler Jan 27, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/releaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- uses: creekorful/goreportcard-action@1f35ced8cdac2cba28c9a2f2288a16aacfd507f9 # v1.0
- uses: anchore/sbom-action/download-syft@0b82b0b1a22399a1c542d4d656f70cd903571b5c
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
uses: sigstore/cosign-installer@7e8b541eb2e61bf99390e1afd4be13a184e9ebc5 # v3.10.1
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
Expand Down
3 changes: 2 additions & 1 deletion .nwa-config
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
nwa:
cmd: "update"
holder: "Project Capsule Authors"
year: "2020-2025"
year: "2020-2026"
spdxids: "Apache-2.0"
path:
- "pkg/**/*.go"
- "cmd/**/*.go"
- "api/**/*.go"
- "internal/**/*.go"
- "controllers/**/*.go"
- "main.go"
mute: false
Expand Down
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,12 @@ dev-setup-capsule: dev-setup-fluxcd

dev-setup-capsule-example: dev-setup-fluxcd
@$(KUBECTL) kustomize --load-restrictor='LoadRestrictionsNone' hack/distro/capsule/example-setup | envsubst | kubectl apply -f -
@$(KUBECTL) create ns wind-test --as joe --as-group projectcapsule.dev
@$(KUBECTL) create ns wind-prod --as joe --as-group projectcapsule.dev
@$(KUBECTL) create ns green-test --as bob --as-group projectcapsule.dev
@$(KUBECTL) create ns green-prod --as bob --as-group projectcapsule.dev
@$(KUBECTL) create ns solar-test --as alice --as-group projectcapsule.dev
@$(KUBECTL) create ns solar-prod --as alice --as-group projectcapsule.dev
@$(KUBECTL) create ns wind-test --as joe --as-group projectcapsule.dev || true
@$(KUBECTL) create ns wind-prod --as joe --as-group projectcapsule.dev || true
@$(KUBECTL) create ns green-test --as bob --as-group projectcapsule.dev || true
@$(KUBECTL) create ns green-prod --as bob --as-group projectcapsule.dev || true
@$(KUBECTL) create ns solar-test --as alice --as-group projectcapsule.dev || true
@$(KUBECTL) create ns solar-prod --as alice --as-group projectcapsule.dev || true

wait-for-helmreleases:
@ echo "Waiting for all HelmReleases to have observedGeneration >= 0..."
Expand Down Expand Up @@ -316,7 +316,7 @@ e2e-build: kind
$(MAKE) e2e-install

.PHONY: e2e-install
e2e-install: ko-build-all
e2e-install: helm-controller-version ko-build-all
$(MAKE) e2e-load-image CLUSTER_NAME=$(CLUSTER_NAME) IMAGE=$(CAPSULE_IMG) VERSION=$(VERSION)
$(HELM) upgrade \
--dependency-update \
Expand Down
2 changes: 1 addition & 1 deletion api/v1beta1/owner_list_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020-2025 Project Capsule Authors
// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package v1beta1
Expand Down
3 changes: 1 addition & 2 deletions api/v1beta1/tenant_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ func (in *Tenant) SetupWebhookWithManager(mgr ctrl.Manager) error {
return nil
}

return ctrl.NewWebhookManagedBy(mgr).
For(in).
return ctrl.NewWebhookManagedBy(mgr, in).
Complete()
}
33 changes: 33 additions & 0 deletions api/v1beta2/namespace_rule_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package v1beta2

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/projectcapsule/capsule/pkg/api"
)

// +kubebuilder:object:generate=true
type NamespaceRule struct {
// Enforce these properties via Rules
NamespaceRuleBody `json:",inline"`

// Select namespaces which are going to usese
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
}

// +kubebuilder:object:generate=true
type NamespaceRuleBody struct {
// Enforcement Rules applied
//+optional
Enforce NamespaceRuleEnforceBody `json:"enforce,omitzero"`
}

// +kubebuilder:object:generate=true
type NamespaceRuleEnforceBody struct {
// Define registries which are allowed to be used within this tenant
// The rules are aggregated, since you can use Regular Expressions the match registry endpoints
Registries []api.OCIRegistry `json:"registries,omitempty"`
}
2 changes: 1 addition & 1 deletion api/v1beta2/resourcepool_func_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020-2025 Project Capsule Authors
// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package v1beta2
Expand Down
2 changes: 1 addition & 1 deletion api/v1beta2/resourcepoolclaim_func_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020-2025 Project Capsule Authors
// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package v1beta2
Expand Down
44 changes: 44 additions & 0 deletions api/v1beta2/rule_status_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package v1beta2

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="Age"
type RuleStatus struct {
metav1.TypeMeta `json:",inline"`

// +optional
metav1.ObjectMeta `json:"metadata,omitzero"`

// +optional
Status RuleStatusSpec `json:"status,omitzero"`
}

// +kubebuilder:object:root=true

// RuleStatusList contains a list of RuleStatus.
type RuleStatusList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitzero"`

Items []RuleStatus `json:"items"`
}

func init() {
SchemeBuilder.Register(&RuleStatus{}, &RuleStatusList{})
}

// RuleStatus contains the accumulated rules applying to namespace it's deployed in.
// +kubebuilder:object:generate=true
type RuleStatusSpec struct {
// Managed Enforcement properties per Namespace (aggregated from rules)
//+optional
Rule NamespaceRuleBody `json:"rule,omitzero"`
}
2 changes: 1 addition & 1 deletion api/v1beta2/tenant_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (in *Tenant) CollectOwners(ctx context.Context, c client.Client, allowPromo
}

func (in *Tenant) GetRoleBindings() []api.AdditionalRoleBindingsSpec {
roleBindings := make([]api.AdditionalRoleBindingsSpec, 0) //nolint:prealloc
roleBindings := make([]api.AdditionalRoleBindingsSpec, 0, len(in.Spec.AdditionalRoleBindings))

for _, owner := range in.Status.Owners {
roleBindings = append(roleBindings, owner.ToAdditionalRolebindings()...)
Expand Down
2 changes: 1 addition & 1 deletion api/v1beta2/tenant_func_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2020-2025 Project Capsule Authors
// Copyright 2020-2026 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package v1beta2
Expand Down
8 changes: 8 additions & 0 deletions api/v1beta2/tenant_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ type TenantStatusNamespaceItem struct {
UID k8stypes.UID `json:"uid,omitempty"`
// Managed Metadata
Metadata *TenantStatusNamespaceMetadata `json:"metadata,omitempty"`
// Managed Metadata
//+optional
Enforce TenantStatusNamespaceEnforcement `json:"enforce,omitzero"`
}

type TenantStatusNamespaceEnforcement struct {
// Registries which are allowed within this namespace
Registries []api.OCIRegistry `json:"registry,omitempty"`
}

type TenantStatusNamespaceMetadata struct {
Expand Down
42 changes: 28 additions & 14 deletions api/v1beta2/tenant_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ type TenantSpec struct {
// Specify Permissions for the Tenant.
// +optional
Permissions Permissions `json:"permissions,omitzero"`
// Specify enforcement specifications for the scope of the Tenant.
// We are moving all configuration enforcement. per namespace into a rule construct.
// It's currently not final.
//
// Read More: https://projectcapsule.dev/docs/tenants/rules/
//+optional
Rules []*NamespaceRule `json:"rules,omitzero"`

// Specifies the owners of the Tenant.
// Optional
Owners api.OwnerListSpec `json:"owners,omitempty"`
Expand All @@ -36,27 +44,13 @@ type TenantSpec struct {
// Specifies options for the Ingress resources, such as allowed hostnames and IngressClass. Optional.
// +optional
IngressOptions IngressOptions `json:"ingressOptions,omitzero"`
// Specifies the trusted Image Registries assigned to the Tenant. Capsule assures that all Pods resources created in the Tenant can use only one of the allowed trusted registries. Optional.
ContainerRegistries *api.AllowedListSpec `json:"containerRegistries,omitempty"`
// Specifies the label to control the placement of pods on a given pool of worker nodes. All namespaces created within the Tenant will have the node selector annotation. This annotation tells the Kubernetes scheduler to place pods on the nodes having the selector label. Optional.
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// Deprecated: Use Tenant Replications instead (https://projectcapsule.dev/docs/replications/)
//
// Specifies the NetworkPolicies assigned to the Tenant. The assigned NetworkPolicies are inherited by any namespace created in the Tenant. Optional.
// +optional
NetworkPolicies api.NetworkPolicySpec `json:"networkPolicies,omitzero"`
// Deprecated: Use Tenant Replications instead (https://projectcapsule.dev/docs/replications/)
//
// Specifies the resource min/max usage restrictions to the Tenant. The assigned values are inherited by any namespace created in the Tenant. Optional.
// +optional
LimitRanges api.LimitRangesSpec `json:"limitRanges,omitzero"`
// Specifies a list of ResourceQuota resources assigned to the Tenant. The assigned values are inherited by any namespace created in the Tenant. The Capsule operator aggregates ResourceQuota at Tenant level, so that the hard quota is never crossed for the given Tenant. This permits the Tenant owner to consume resources in the Tenant regardless of the namespace. Optional.
// +optional
ResourceQuota api.ResourceQuotaSpec `json:"resourceQuotas,omitzero"`
// Specifies additional RoleBindings assigned to the Tenant. Capsule will ensure that all namespaces in the Tenant always contain the RoleBinding for the given ClusterRole. Optional.
AdditionalRoleBindings []api.AdditionalRoleBindingsSpec `json:"additionalRoleBindings,omitempty"`
// Specify the allowed values for the imagePullPolicies option in Pod resources. Capsule assures that all Pod resources created in the Tenant can use only one of the allowed policy. Optional.
ImagePullPolicies []api.ImagePullPolicySpec `json:"imagePullPolicies,omitempty"`
// Specifies the allowed RuntimeClasses assigned to the Tenant.
// Capsule assures that all Pods resources created in the Tenant can use only one of the allowed RuntimeClasses.
// Optional.
Expand Down Expand Up @@ -87,6 +81,26 @@ type TenantSpec struct {
// If unset, Tenant uses CapsuleConfiguration's forceTenantPrefix
// Optional
ForceTenantPrefix *bool `json:"forceTenantPrefix,omitempty"`

// Deprecated: Use Enforcement.Registries instead
//
// Specifies the trusted Image Registries assigned to the Tenant. Capsule assures that all Pods resources created in the Tenant can use only one of the allowed trusted registries. Optional.
ContainerRegistries *api.AllowedListSpec `json:"containerRegistries,omitempty"`
// Deprecated: Use Enforcement.Registries instead
//
// Specify the allowed values for the imagePullPolicies option in Pod resources. Capsule assures that all Pod resources created in the Tenant can use only one of the allowed policy. Optional.
ImagePullPolicies []api.ImagePullPolicySpec `json:"imagePullPolicies,omitempty"`

// Deprecated: Use Tenant Replications instead (https://projectcapsule.dev/docs/replications/)
//
// Specifies the NetworkPolicies assigned to the Tenant. The assigned NetworkPolicies are inherited by any namespace created in the Tenant. Optional.
// +optional
NetworkPolicies api.NetworkPolicySpec `json:"networkPolicies,omitzero"`
// Deprecated: Use Tenant Replications instead (https://projectcapsule.dev/docs/replications/)
//
// Specifies the resource min/max usage restrictions to the Tenant. The assigned values are inherited by any namespace created in the Tenant. Optional.
// +optional
LimitRanges api.LimitRangesSpec `json:"limitRanges,omitzero"`
}

type Permissions struct {
Expand Down
Loading
Loading