mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-02-14 18:09:58 +00:00
feat: add dynamic capsule user evaluation (#1811)
* chore: improve dev targets Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * feat(controller): implement deterministic rolebinding reflection Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * feat(controller): capsule users are determined from configuration status Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * feat(tenantowners): added agreggate option - tenantowners are always considered capsule users Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * feat(tenantowner): add implicit aggregation for tenants Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * chore: remove helm flags Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> * fix(config): remove usergroups default Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com> --------- Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
This commit is contained in:
14
api/v1beta2/capsuleconfiguration_status.go
Normal file
14
api/v1beta2/capsuleconfiguration_status.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
)
|
||||
|
||||
// CapsuleConfigurationStatus defines the Capsule configuration status.
|
||||
type CapsuleConfigurationStatus struct {
|
||||
// Users which are considered Capsule Users and are bound to the Capsule Tenant construct.
|
||||
Users api.UserListSpec `json:"users,omitempty"`
|
||||
}
|
||||
@@ -21,7 +21,6 @@ type CapsuleConfigurationSpec struct {
|
||||
// Deprecated: use users property instead (https://projectcapsule.dev/docs/operating/setup/configuration/#users)
|
||||
//
|
||||
// Names of the groups considered as Capsule users.
|
||||
// +kubebuilder:default={capsule.clastix.io}
|
||||
UserGroups []string `json:"userGroups,omitempty"`
|
||||
// Define groups which when found in the request of a user will be ignored by the Capsule
|
||||
// this might be useful if you have one group where all the users are in, but you want to separate administrators from normal users with additional groups.
|
||||
@@ -79,6 +78,7 @@ type CapsuleResources struct {
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:storageversion
|
||||
|
||||
@@ -90,6 +90,9 @@ type CapsuleConfiguration struct {
|
||||
metav1.ObjectMeta `json:"metadata,omitzero"`
|
||||
|
||||
Spec CapsuleConfigurationSpec `json:"spec"`
|
||||
|
||||
// +optional
|
||||
Status CapsuleConfigurationStatus `json:"status,omitzero"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
@@ -62,7 +62,7 @@ func (in *Tenant) CollectOwners(ctx context.Context, c client.Client, allowPromo
|
||||
}
|
||||
|
||||
// Dedicated Owner Objects
|
||||
listed, err := in.Spec.Permissions.ListMatchingOwners(ctx, c)
|
||||
listed, err := in.Spec.Permissions.ListMatchingOwners(ctx, c, in.GetName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -74,6 +74,18 @@ func (in *Tenant) CollectOwners(ctx context.Context, c client.Client, allowPromo
|
||||
return owners, nil
|
||||
}
|
||||
|
||||
func (in *Tenant) GetRoleBindings() []api.AdditionalRoleBindingsSpec {
|
||||
roleBindings := make([]api.AdditionalRoleBindingsSpec, 0)
|
||||
|
||||
for _, owner := range in.Status.Owners {
|
||||
roleBindings = append(roleBindings, owner.ToAdditionalRolebindings()...)
|
||||
}
|
||||
|
||||
roleBindings = append(roleBindings, in.Spec.AdditionalRoleBindings...)
|
||||
|
||||
return roleBindings
|
||||
}
|
||||
|
||||
func (in *Tenant) IsFull() bool {
|
||||
// we don't have limits on assigned Namespaces
|
||||
if in.Spec.NamespaceOptions == nil || in.Spec.NamespaceOptions.Quota == nil {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/api"
|
||||
"github.com/projectcapsule/capsule/pkg/api/meta"
|
||||
"github.com/projectcapsule/capsule/pkg/api/misc"
|
||||
)
|
||||
|
||||
@@ -98,9 +99,16 @@ type Permissions struct {
|
||||
func (p *Permissions) ListMatchingOwners(
|
||||
ctx context.Context,
|
||||
c client.Client,
|
||||
tnt string,
|
||||
opts ...client.ListOption,
|
||||
) ([]*TenantOwner, error) {
|
||||
return misc.ListBySelectors[*TenantOwner](ctx, c, &TenantOwnerList{}, p.MatchOwners)
|
||||
defaultSelector := &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
meta.NewTenantLabel: tnt,
|
||||
},
|
||||
}
|
||||
|
||||
return misc.ListBySelectors[*TenantOwner](ctx, c, &TenantOwnerList{}, append(p.MatchOwners, defaultSelector))
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
@@ -11,7 +11,14 @@ import (
|
||||
|
||||
// TenantOwnerSpec defines the desired state of TenantOwner.
|
||||
type TenantOwnerSpec struct {
|
||||
// Subject
|
||||
api.CoreOwnerSpec `json:",inline"`
|
||||
|
||||
// Adds the given subject as capsule user. When enabled this subject does not have to be
|
||||
// mentioned in the CapsuleConfiguration as Capsule User. In almost all scenarios Tenant Owners
|
||||
// must be Capsule Users.
|
||||
//+kubebuilder:default:=true
|
||||
Aggregate bool `json:"aggregate"`
|
||||
}
|
||||
|
||||
// TenantOwnerStatus defines the observed state of TenantOwner.
|
||||
|
||||
@@ -43,6 +43,7 @@ func (in *CapsuleConfiguration) DeepCopyInto(out *CapsuleConfiguration) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapsuleConfiguration.
|
||||
@@ -141,6 +142,26 @@ func (in *CapsuleConfigurationSpec) DeepCopy() *CapsuleConfigurationSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CapsuleConfigurationStatus) DeepCopyInto(out *CapsuleConfigurationStatus) {
|
||||
*out = *in
|
||||
if in.Users != nil {
|
||||
in, out := &in.Users, &out.Users
|
||||
*out = make(api.UserListSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapsuleConfigurationStatus.
|
||||
func (in *CapsuleConfigurationStatus) DeepCopy() *CapsuleConfigurationStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CapsuleConfigurationStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CapsuleResources) DeepCopyInto(out *CapsuleResources) {
|
||||
*out = *in
|
||||
|
||||
Reference in New Issue
Block a user