mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-02-14 18:09:58 +00:00
refactor(api): switching to v1beta2 as storage version
This commit is contained in:
12
pkg/api/annotations.go
Normal file
12
pkg/api/annotations.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2020-2021 Clastix Labs
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package api
|
||||
|
||||
const (
|
||||
ForbiddenNamespaceLabelsAnnotation = "capsule.clastix.io/forbidden-namespace-labels"
|
||||
ForbiddenNamespaceLabelsRegexpAnnotation = "capsule.clastix.io/forbidden-namespace-labels-regexp"
|
||||
ForbiddenNamespaceAnnotationsAnnotation = "capsule.clastix.io/forbidden-namespace-annotations"
|
||||
ForbiddenNamespaceAnnotationsRegexpAnnotation = "capsule.clastix.io/forbidden-namespace-annotations-regexp"
|
||||
ProtectedTenantAnnotation = "capsule.clastix.io/protected"
|
||||
)
|
||||
@@ -6,32 +6,30 @@ package configuration
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
capsulev1alpha1 "github.com/clastix/capsule/api/v1alpha1"
|
||||
capsulev1beta1 "github.com/clastix/capsule/pkg/api"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsuleapi "github.com/clastix/capsule/pkg/api"
|
||||
)
|
||||
|
||||
// capsuleConfiguration is the Capsule Configuration retrieval mode
|
||||
// using a closure that provides the desired configuration.
|
||||
type capsuleConfiguration struct {
|
||||
retrievalFn func() *capsulev1alpha1.CapsuleConfiguration
|
||||
retrievalFn func() *capsulev1beta2.CapsuleConfiguration
|
||||
}
|
||||
|
||||
func NewCapsuleConfiguration(ctx context.Context, client client.Client, name string) Configuration {
|
||||
return &capsuleConfiguration{retrievalFn: func() *capsulev1alpha1.CapsuleConfiguration {
|
||||
config := &capsulev1alpha1.CapsuleConfiguration{}
|
||||
return &capsuleConfiguration{retrievalFn: func() *capsulev1beta2.CapsuleConfiguration {
|
||||
config := &capsulev1beta2.CapsuleConfiguration{}
|
||||
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: name}, config); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return &capsulev1alpha1.CapsuleConfiguration{
|
||||
Spec: capsulev1alpha1.CapsuleConfigurationSpec{
|
||||
return &capsulev1beta2.CapsuleConfiguration{
|
||||
Spec: capsulev1beta2.CapsuleConfigurationSpec{
|
||||
UserGroups: []string{"capsule.clastix.io"},
|
||||
ForceTenantPrefix: false,
|
||||
ProtectedNamespaceRegexpString: "",
|
||||
@@ -45,7 +43,7 @@ func NewCapsuleConfiguration(ctx context.Context, client client.Client, name str
|
||||
}}
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) ProtectedNamespaceRegexp() (*regexp.Regexp, error) {
|
||||
func (c *capsuleConfiguration) ProtectedNamespaceRegexp() (*regexp.Regexp, error) {
|
||||
expr := c.retrievalFn().Spec.ProtectedNamespaceRegexpString
|
||||
if len(expr) == 0 {
|
||||
return nil, nil // nolint:nilnil
|
||||
@@ -59,120 +57,46 @@ func (c capsuleConfiguration) ProtectedNamespaceRegexp() (*regexp.Regexp, error)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) ForceTenantPrefix() bool {
|
||||
func (c *capsuleConfiguration) ForceTenantPrefix() bool {
|
||||
return c.retrievalFn().Spec.ForceTenantPrefix
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) TLSSecretName() (name string) {
|
||||
name = TLSSecretName
|
||||
|
||||
if c.retrievalFn().Annotations == nil {
|
||||
return
|
||||
}
|
||||
|
||||
v, ok := c.retrievalFn().Annotations[capsulev1alpha1.TLSSecretNameAnnotation]
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return
|
||||
func (c *capsuleConfiguration) TLSSecretName() (name string) {
|
||||
return c.retrievalFn().Spec.CapsuleResources.TLSSecretName
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) EnableTLSConfiguration() bool {
|
||||
annotationValue, ok := c.retrievalFn().Annotations[capsulev1alpha1.EnableTLSConfigurationAnnotationName]
|
||||
|
||||
if ok {
|
||||
value, err := strconv.ParseBool(annotationValue)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
return false
|
||||
func (c *capsuleConfiguration) EnableTLSConfiguration() bool {
|
||||
return c.retrievalFn().Spec.EnableTLSReconciler
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) MutatingWebhookConfigurationName() (name string) {
|
||||
name = MutatingWebhookConfigurationName
|
||||
|
||||
if c.retrievalFn().Annotations == nil {
|
||||
return
|
||||
}
|
||||
|
||||
v, ok := c.retrievalFn().Annotations[capsulev1alpha1.MutatingWebhookConfigurationName]
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return
|
||||
func (c *capsuleConfiguration) MutatingWebhookConfigurationName() (name string) {
|
||||
return c.retrievalFn().Spec.CapsuleResources.MutatingWebhookConfigurationName
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) TenantCRDName() string {
|
||||
func (c *capsuleConfiguration) TenantCRDName() string {
|
||||
return TenantCRDName
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) ValidatingWebhookConfigurationName() (name string) {
|
||||
name = ValidatingWebhookConfigurationName
|
||||
|
||||
if c.retrievalFn().Annotations == nil {
|
||||
return
|
||||
}
|
||||
|
||||
v, ok := c.retrievalFn().Annotations[capsulev1alpha1.ValidatingWebhookConfigurationName]
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return
|
||||
func (c *capsuleConfiguration) ValidatingWebhookConfigurationName() (name string) {
|
||||
return c.retrievalFn().Spec.CapsuleResources.ValidatingWebhookConfigurationName
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) UserGroups() []string {
|
||||
func (c *capsuleConfiguration) UserGroups() []string {
|
||||
return c.retrievalFn().Spec.UserGroups
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) hasForbiddenNodeLabelsAnnotations() bool {
|
||||
if _, ok := c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeLabelsAnnotation]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
if _, ok := c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeLabelsRegexpAnnotation]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c capsuleConfiguration) hasForbiddenNodeAnnotationsAnnotations() bool {
|
||||
if _, ok := c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeAnnotationsAnnotation]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
if _, ok := c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeAnnotationsRegexpAnnotation]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *capsuleConfiguration) ForbiddenUserNodeLabels() *capsulev1beta1.ForbiddenListSpec {
|
||||
if !c.hasForbiddenNodeLabelsAnnotations() {
|
||||
func (c *capsuleConfiguration) ForbiddenUserNodeLabels() *capsuleapi.ForbiddenListSpec {
|
||||
if c.retrievalFn().Spec.NodeMetadata == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &capsulev1beta1.ForbiddenListSpec{
|
||||
Exact: strings.Split(c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeLabelsAnnotation], ","),
|
||||
Regex: c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeLabelsRegexpAnnotation],
|
||||
}
|
||||
return &c.retrievalFn().Spec.NodeMetadata.ForbiddenLabels
|
||||
}
|
||||
|
||||
func (c *capsuleConfiguration) ForbiddenUserNodeAnnotations() *capsulev1beta1.ForbiddenListSpec {
|
||||
if !c.hasForbiddenNodeAnnotationsAnnotations() {
|
||||
func (c *capsuleConfiguration) ForbiddenUserNodeAnnotations() *capsuleapi.ForbiddenListSpec {
|
||||
if c.retrievalFn().Spec.NodeMetadata == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &capsulev1beta1.ForbiddenListSpec{
|
||||
Exact: strings.Split(c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeAnnotationsAnnotation], ","),
|
||||
Regex: c.retrievalFn().Annotations[capsulev1alpha1.ForbiddenNodeAnnotationsRegexpAnnotation],
|
||||
}
|
||||
return &c.retrievalFn().Spec.NodeMetadata.ForbiddenAnnotations
|
||||
}
|
||||
|
||||
@@ -6,14 +6,11 @@ package configuration
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/pkg/api"
|
||||
capsuleapi "github.com/clastix/capsule/pkg/api"
|
||||
)
|
||||
|
||||
const (
|
||||
TLSSecretName = "capsule-tls"
|
||||
MutatingWebhookConfigurationName = "capsule-mutating-webhook-configuration"
|
||||
ValidatingWebhookConfigurationName = "capsule-validating-webhook-configuration"
|
||||
TenantCRDName = "tenants.capsule.clastix.io"
|
||||
TenantCRDName = "tenants.capsule.clastix.io"
|
||||
)
|
||||
|
||||
type Configuration interface {
|
||||
@@ -27,6 +24,6 @@ type Configuration interface {
|
||||
ValidatingWebhookConfigurationName() string
|
||||
TenantCRDName() string
|
||||
UserGroups() []string
|
||||
ForbiddenUserNodeLabels() *capsulev1beta1.ForbiddenListSpec
|
||||
ForbiddenUserNodeAnnotations() *capsulev1beta1.ForbiddenListSpec
|
||||
ForbiddenUserNodeLabels() *capsuleapi.ForbiddenListSpec
|
||||
ForbiddenUserNodeAnnotations() *capsuleapi.ForbiddenListSpec
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/indexer/ingress"
|
||||
"github.com/clastix/capsule/pkg/indexer/namespace"
|
||||
@@ -31,7 +30,6 @@ type CustomIndexer interface {
|
||||
|
||||
func AddToManager(ctx context.Context, log logr.Logger, mgr manager.Manager) error {
|
||||
indexers := []CustomIndexer{
|
||||
tenant.NamespacesReference{Obj: &capsulev1beta1.Tenant{}},
|
||||
tenant.NamespacesReference{Obj: &capsulev1beta2.Tenant{}},
|
||||
tenant.OwnerReference{},
|
||||
namespace.OwnerReference{},
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
type OwnerReference struct{}
|
||||
@@ -32,7 +32,7 @@ func (o OwnerReference) Func() client.IndexerFunc {
|
||||
}
|
||||
|
||||
for _, or := range ns.OwnerReferences {
|
||||
if or.APIVersion == capsulev1beta1.GroupVersion.String() {
|
||||
if or.APIVersion == capsulev1beta2.GroupVersion.String() {
|
||||
res = append(res, or.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@ import (
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/utils"
|
||||
)
|
||||
|
||||
type OwnerReference struct{}
|
||||
|
||||
func (o OwnerReference) Object() client.Object {
|
||||
return &capsulev1beta1.Tenant{}
|
||||
return &capsulev1beta2.Tenant{}
|
||||
}
|
||||
|
||||
func (o OwnerReference) Field() string {
|
||||
@@ -24,9 +24,9 @@ func (o OwnerReference) Field() string {
|
||||
|
||||
func (o OwnerReference) Func() client.IndexerFunc {
|
||||
return func(object client.Object) []string {
|
||||
tenant, ok := object.(*capsulev1beta1.Tenant)
|
||||
tenant, ok := object.(*capsulev1beta2.Tenant)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("expected type *capsulev1beta1.Tenant, got %T", tenant))
|
||||
panic(fmt.Errorf("expected type *capsulev1beta2.Tenant, got %T", tenant))
|
||||
}
|
||||
|
||||
return utils.GetOwnersWithKinds(tenant)
|
||||
|
||||
@@ -8,14 +8,14 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
const (
|
||||
NodeSelectorAnnotation = "scheduler.alpha.kubernetes.io/node-selector"
|
||||
)
|
||||
|
||||
func BuildNodeSelector(tnt *capsulev1beta1.Tenant, nsAnnotations map[string]string) map[string]string {
|
||||
func BuildNodeSelector(tnt *capsulev1beta2.Tenant, nsAnnotations map[string]string) map[string]string {
|
||||
if nsAnnotations == nil {
|
||||
nsAnnotations = make(map[string]string)
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ package utils
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
func GetOwnersWithKinds(tenant *capsulev1beta1.Tenant) (owners []string) {
|
||||
func GetOwnersWithKinds(tenant *capsulev1beta2.Tenant) (owners []string) {
|
||||
for _, owner := range tenant.Spec.Owners {
|
||||
owners = append(owners, fmt.Sprintf("%s:%s", owner.Kind.String(), owner.Name))
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
func tenantFromIngress(ctx context.Context, c client.Client, ingress Ingress) (*capsulev1beta1.Tenant, error) {
|
||||
tenantList := &capsulev1beta1.TenantList{}
|
||||
func tenantFromIngress(ctx context.Context, c client.Client, ingress Ingress) (*capsulev1beta2.Tenant, error) {
|
||||
tenantList := &capsulev1beta2.TenantList{}
|
||||
if err := c.List(ctx, tenantList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", ingress.Namespace()),
|
||||
}); err != nil {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
@@ -34,7 +34,7 @@ func (r *class) OnCreate(client client.Client, decoder *admission.Decoder, recor
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
var tenant *capsulev1beta1.Tenant
|
||||
var tenant *capsulev1beta2.Tenant
|
||||
|
||||
tenant, err = tenantFromIngress(ctx, client, ingress)
|
||||
if err != nil {
|
||||
@@ -75,7 +75,7 @@ func (r *class) OnUpdate(client client.Client, decoder *admission.Decoder, recor
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
var tenant *capsulev1beta1.Tenant
|
||||
var tenant *capsulev1beta2.Tenant
|
||||
|
||||
tenant, err = tenantFromIngress(ctx, client, ingress)
|
||||
if err != nil {
|
||||
@@ -114,7 +114,7 @@ func (r *class) OnDelete(client.Client, *admission.Decoder, record.EventRecorder
|
||||
}
|
||||
}
|
||||
|
||||
func (r *class) validateClass(tenant capsulev1beta1.Tenant, ingressClass *string) error {
|
||||
func (r *class) validateClass(tenant capsulev1beta2.Tenant, ingressClass *string) error {
|
||||
if tenant.Spec.IngressOptions.AllowedClasses == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/api"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
"github.com/clastix/capsule/pkg/indexer/ingress"
|
||||
@@ -42,7 +42,7 @@ func (r *collision) OnCreate(client client.Client, decoder *admission.Decoder, r
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
var tenant *capsulev1beta1.Tenant
|
||||
var tenant *capsulev1beta2.Tenant
|
||||
|
||||
tenant, err = tenantFromIngress(ctx, client, ing)
|
||||
if err != nil {
|
||||
@@ -77,7 +77,7 @@ func (r *collision) OnUpdate(client client.Client, decoder *admission.Decoder, r
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
var tenant *capsulev1beta1.Tenant
|
||||
var tenant *capsulev1beta2.Tenant
|
||||
|
||||
tenant, err = tenantFromIngress(ctx, client, ing)
|
||||
if err != nil {
|
||||
@@ -129,7 +129,7 @@ func (r *collision) validateCollision(ctx context.Context, clt client.Client, in
|
||||
// nolint:exhaustive
|
||||
switch scope {
|
||||
case api.HostnameCollisionScopeCluster:
|
||||
tenantList := &capsulev1beta1.TenantList{}
|
||||
tenantList := &capsulev1beta2.TenantList{}
|
||||
if err := clt.List(ctx, tenantList); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -140,7 +140,7 @@ func (r *collision) validateCollision(ctx context.Context, clt client.Client, in
|
||||
case api.HostnameCollisionScopeTenant:
|
||||
selector := client.MatchingFieldsSelector{Selector: fields.OneTermEqualSelector(".status.namespaces", ing.Namespace())}
|
||||
|
||||
tenantList := &capsulev1beta1.TenantList{}
|
||||
tenantList := &capsulev1beta2.TenantList{}
|
||||
if err := clt.List(ctx, tenantList, selector); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
@@ -35,7 +35,7 @@ func (r *hostnames) OnCreate(c client.Client, decoder *admission.Decoder, record
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
var tenant *capsulev1beta1.Tenant
|
||||
var tenant *capsulev1beta2.Tenant
|
||||
|
||||
tenant, err = tenantFromIngress(ctx, c, ingress)
|
||||
if err != nil {
|
||||
@@ -76,7 +76,7 @@ func (r *hostnames) OnUpdate(c client.Client, decoder *admission.Decoder, record
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
var tenant *capsulev1beta1.Tenant
|
||||
var tenant *capsulev1beta2.Tenant
|
||||
|
||||
tenant, err = tenantFromIngress(ctx, c, ingress)
|
||||
if err != nil {
|
||||
@@ -116,7 +116,7 @@ func (r *hostnames) OnDelete(client.Client, *admission.Decoder, record.EventReco
|
||||
}
|
||||
}
|
||||
|
||||
func (r *hostnames) validateHostnames(tenant capsulev1beta1.Tenant, hostnames sets.String) error {
|
||||
func (r *hostnames) validateHostnames(tenant capsulev1beta2.Tenant, hostnames sets.String) error {
|
||||
if tenant.Spec.IngressOptions.AllowedHostnames == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -44,7 +44,7 @@ func (h *wildcard) OnUpdate(client client.Client, decoder *admission.Decoder, re
|
||||
}
|
||||
|
||||
func (h *wildcard) wildcardHandler(ctx context.Context, clt client.Client, req admission.Request, recorder record.EventRecorder, decoder *admission.Decoder) *admission.Response {
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
|
||||
if err := clt.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", req.Namespace),
|
||||
@@ -59,8 +59,7 @@ func (h *wildcard) wildcardHandler(ctx context.Context, clt client.Client, req a
|
||||
|
||||
tnt := tntList.Items[0]
|
||||
|
||||
// Check if Annotation in manifest has value "capsule.clastix.io/deny-wildcard" set to "true".
|
||||
if tnt.IsWildcardDenied() {
|
||||
if !tnt.Spec.IngressOptions.AllowWildcardHostnames {
|
||||
// Retrieve ingress resource from request.
|
||||
ingress, err := ingressFromRequest(req, decoder)
|
||||
if err != nil {
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/pkg/api"
|
||||
capsuleapi "github.com/clastix/capsule/pkg/api"
|
||||
)
|
||||
|
||||
// nolint:predeclared
|
||||
func appendForbiddenError(spec *capsulev1beta1.ForbiddenListSpec) (append string) {
|
||||
func appendForbiddenError(spec *capsuleapi.ForbiddenListSpec) (append string) {
|
||||
append += "Forbidden are "
|
||||
if len(spec.Exact) > 0 {
|
||||
append += fmt.Sprintf("one of the following (%s)", strings.Join(spec.Exact, ", "))
|
||||
@@ -39,10 +39,10 @@ func (namespaceQuotaExceededError) Error() string {
|
||||
|
||||
type namespaceLabelForbiddenError struct {
|
||||
label string
|
||||
spec *capsulev1beta1.ForbiddenListSpec
|
||||
spec *capsuleapi.ForbiddenListSpec
|
||||
}
|
||||
|
||||
func NewNamespaceLabelForbiddenError(label string, forbiddenSpec *capsulev1beta1.ForbiddenListSpec) error {
|
||||
func NewNamespaceLabelForbiddenError(label string, forbiddenSpec *capsuleapi.ForbiddenListSpec) error {
|
||||
return &namespaceLabelForbiddenError{
|
||||
label: label,
|
||||
spec: forbiddenSpec,
|
||||
@@ -55,10 +55,10 @@ func (f namespaceLabelForbiddenError) Error() string {
|
||||
|
||||
type namespaceAnnotationForbiddenError struct {
|
||||
annotation string
|
||||
spec *capsulev1beta1.ForbiddenListSpec
|
||||
spec *capsuleapi.ForbiddenListSpec
|
||||
}
|
||||
|
||||
func NewNamespaceAnnotationForbiddenError(annotation string, forbiddenSpec *capsulev1beta1.ForbiddenListSpec) error {
|
||||
func NewNamespaceAnnotationForbiddenError(annotation string, forbiddenSpec *capsuleapi.ForbiddenListSpec) error {
|
||||
return &namespaceAnnotationForbiddenError{
|
||||
annotation: annotation,
|
||||
spec: forbiddenSpec,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
@@ -36,12 +36,12 @@ func (r *freezedHandler) OnCreate(client client.Client, decoder *admission.Decod
|
||||
|
||||
for _, objectRef := range ns.ObjectMeta.OwnerReferences {
|
||||
// retrieving the selected Tenant
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: objectRef.Name}, tnt); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
if tnt.IsCordoned() {
|
||||
if tnt.Spec.Cordoned {
|
||||
recorder.Eventf(tnt, corev1.EventTypeWarning, "TenantFreezed", "Namespace %s cannot be attached, the current Tenant is freezed", ns.GetName())
|
||||
|
||||
response := admission.Denied("the selected Tenant is freezed")
|
||||
@@ -56,7 +56,7 @@ func (r *freezedHandler) OnCreate(client client.Client, decoder *admission.Decod
|
||||
|
||||
func (r *freezedHandler) OnDelete(c client.Client, _ *admission.Decoder, recorder record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
if err := c.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", req.Name),
|
||||
}); err != nil {
|
||||
@@ -69,7 +69,7 @@ func (r *freezedHandler) OnDelete(c client.Client, _ *admission.Decoder, recorde
|
||||
|
||||
tnt := tntList.Items[0]
|
||||
|
||||
if tnt.IsCordoned() && utils.IsCapsuleUser(ctx, req, c, r.configuration.UserGroups()) {
|
||||
if tnt.Spec.Cordoned && utils.IsCapsuleUser(ctx, req, c, r.configuration.UserGroups()) {
|
||||
recorder.Eventf(&tnt, corev1.EventTypeWarning, "TenantFreezed", "Namespace %s cannot be deleted, the current Tenant is freezed", req.Name)
|
||||
|
||||
response := admission.Denied("the selected Tenant is freezed")
|
||||
@@ -88,7 +88,7 @@ func (r *freezedHandler) OnUpdate(c client.Client, decoder *admission.Decoder, r
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
if err := c.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", ns.Name),
|
||||
}); err != nil {
|
||||
@@ -101,7 +101,7 @@ func (r *freezedHandler) OnUpdate(c client.Client, decoder *admission.Decoder, r
|
||||
|
||||
tnt := tntList.Items[0]
|
||||
|
||||
if tnt.IsCordoned() && utils.IsCapsuleUser(ctx, req, c, r.configuration.UserGroups()) {
|
||||
if tnt.Spec.Cordoned && utils.IsCapsuleUser(ctx, req, c, r.configuration.UserGroups()) {
|
||||
recorder.Eventf(&tnt, corev1.EventTypeWarning, "TenantFreezed", "Namespace %s cannot be updated, the current Tenant is freezed", ns.GetName())
|
||||
|
||||
response := admission.Denied("the selected Tenant is freezed")
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
utils2 "github.com/clastix/capsule/pkg/utils"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsuleutils "github.com/clastix/capsule/pkg/utils"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -47,7 +47,7 @@ func (r *patchHandler) OnUpdate(c client.Client, decoder *admission.Decoder, rec
|
||||
}
|
||||
|
||||
// Get Tenant Label
|
||||
ln, err := utils2.GetTypeLabel(&capsulev1beta1.Tenant{})
|
||||
ln, err := capsuleutils.GetTypeLabel(&capsulev1beta2.Tenant{})
|
||||
if err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
|
||||
@@ -59,7 +59,7 @@ func (r *patchHandler) OnUpdate(c client.Client, decoder *admission.Decoder, rec
|
||||
|
||||
if label, ok := ns.ObjectMeta.Labels[ln]; ok {
|
||||
// retrieving the selected Tenant
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
if err = c.Get(ctx, types.NamespacedName{Name: label}, tnt); err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
@@ -46,7 +46,7 @@ func (r *prefixHandler) OnCreate(clt client.Client, decoder *admission.Decoder,
|
||||
}
|
||||
|
||||
if r.configuration.ForceTenantPrefix() {
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
|
||||
for _, or := range ns.ObjectMeta.OwnerReferences {
|
||||
// retrieving the selected Tenant
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -32,7 +32,7 @@ func (r *quotaHandler) OnCreate(client client.Client, decoder *admission.Decoder
|
||||
|
||||
for _, objectRef := range ns.ObjectMeta.OwnerReferences {
|
||||
// retrieving the selected Tenant
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: objectRef.Name}, tnt); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,9 +24,9 @@ func UserMetadataHandler() capsulewebhook.Handler {
|
||||
return &userMetadataHandler{}
|
||||
}
|
||||
|
||||
func (r *userMetadataHandler) validateUserMetadata(tnt *capsulev1beta1.Tenant, recorder record.EventRecorder, labels map[string]string, annotations map[string]string) *admission.Response {
|
||||
if tnt.ForbiddenUserNamespaceLabels() != nil {
|
||||
forbiddenLabels := tnt.ForbiddenUserNamespaceLabels()
|
||||
func (r *userMetadataHandler) validateUserMetadata(tnt *capsulev1beta2.Tenant, recorder record.EventRecorder, labels map[string]string, annotations map[string]string) *admission.Response {
|
||||
if tnt.Spec.NamespaceOptions != nil {
|
||||
forbiddenLabels := tnt.Spec.NamespaceOptions.ForbiddenLabels
|
||||
|
||||
for label := range labels {
|
||||
var forbidden, matched bool
|
||||
@@ -36,28 +36,30 @@ func (r *userMetadataHandler) validateUserMetadata(tnt *capsulev1beta1.Tenant, r
|
||||
if forbidden || matched {
|
||||
recorder.Eventf(tnt, corev1.EventTypeWarning, "ForbiddenNamespaceLabel", fmt.Sprintf("Label %s is forbidden for a namespaces of the current Tenant ", label))
|
||||
|
||||
response := admission.Denied(NewNamespaceLabelForbiddenError(label, forbiddenLabels).Error())
|
||||
response := admission.Denied(NewNamespaceLabelForbiddenError(label, &forbiddenLabels).Error())
|
||||
|
||||
return &response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if tnt.ForbiddenUserNamespaceAnnotations() != nil {
|
||||
forbiddenAnnotations := tnt.ForbiddenUserNamespaceLabels()
|
||||
if tnt.Spec.NamespaceOptions == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for annotation := range annotations {
|
||||
var forbidden, matched bool
|
||||
forbidden = forbiddenAnnotations.ExactMatch(annotation)
|
||||
matched = forbiddenAnnotations.RegexMatch(annotation)
|
||||
forbiddenAnnotations := tnt.Spec.NamespaceOptions.ForbiddenLabels
|
||||
|
||||
if forbidden || matched {
|
||||
recorder.Eventf(tnt, corev1.EventTypeWarning, "ForbiddenNamespaceAnnotation", fmt.Sprintf("Annotation %s is forbidden for a namespaces of the current Tenant ", annotation))
|
||||
for annotation := range annotations {
|
||||
var forbidden, matched bool
|
||||
forbidden = forbiddenAnnotations.ExactMatch(annotation)
|
||||
matched = forbiddenAnnotations.RegexMatch(annotation)
|
||||
|
||||
response := admission.Denied(NewNamespaceAnnotationForbiddenError(annotation, forbiddenAnnotations).Error())
|
||||
if forbidden || matched {
|
||||
recorder.Eventf(tnt, corev1.EventTypeWarning, "ForbiddenNamespaceAnnotation", fmt.Sprintf("Annotation %s is forbidden for a namespaces of the current Tenant ", annotation))
|
||||
|
||||
return &response
|
||||
}
|
||||
response := admission.Denied(NewNamespaceAnnotationForbiddenError(annotation, &forbiddenAnnotations).Error())
|
||||
|
||||
return &response
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ func (r *userMetadataHandler) OnCreate(client client.Client, decoder *admission.
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
for _, objectRef := range ns.ObjectMeta.OwnerReferences {
|
||||
// retrieving the selected Tenant
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: objectRef.Name}, tnt); err != nil {
|
||||
@@ -104,7 +106,7 @@ func (r *userMetadataHandler) OnUpdate(client client.Client, decoder *admission.
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
for _, objectRef := range newNs.ObjectMeta.OwnerReferences {
|
||||
// retrieving the selected Tenant
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: objectRef.Name}, tnt); err != nil {
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
utils2 "github.com/clastix/capsule/pkg/utils"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsuleutils "github.com/clastix/capsule/pkg/utils"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -31,7 +31,7 @@ func (r *handler) OnCreate(client.Client, *admission.Decoder, record.EventRecord
|
||||
}
|
||||
}
|
||||
|
||||
func (r *handler) generic(ctx context.Context, req admission.Request, client client.Client, _ *admission.Decoder) (*capsulev1beta1.Tenant, error) {
|
||||
func (r *handler) generic(ctx context.Context, req admission.Request, client client.Client, _ *admission.Decoder) (*capsulev1beta2.Tenant, error) {
|
||||
var err error
|
||||
|
||||
np := &networkingv1.NetworkPolicy{}
|
||||
@@ -39,9 +39,9 @@ func (r *handler) generic(ctx context.Context, req admission.Request, client cli
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
|
||||
l, _ := utils2.GetTypeLabel(&capsulev1beta1.Tenant{})
|
||||
l, _ := capsuleutils.GetTypeLabel(&capsulev1beta2.Tenant{})
|
||||
if v, ok := np.GetLabels()[l]; ok {
|
||||
if err = client.Get(ctx, types.NamespacedName{Name: v}, tnt); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/pkg/api"
|
||||
capsulev1beta2 "github.com/clastix/capsule/pkg/api"
|
||||
)
|
||||
|
||||
// nolint:predeclared
|
||||
func appendForbiddenError(spec *capsulev1beta1.ForbiddenListSpec) (append string) {
|
||||
func appendForbiddenError(spec *capsulev1beta2.ForbiddenListSpec) (append string) {
|
||||
append += "Forbidden are "
|
||||
if len(spec.Exact) > 0 {
|
||||
append += fmt.Sprintf("one of the following (%s)", strings.Join(spec.Exact, ", "))
|
||||
@@ -28,10 +28,10 @@ func appendForbiddenError(spec *capsulev1beta1.ForbiddenListSpec) (append string
|
||||
}
|
||||
|
||||
type nodeLabelForbiddenError struct {
|
||||
spec *capsulev1beta1.ForbiddenListSpec
|
||||
spec *capsulev1beta2.ForbiddenListSpec
|
||||
}
|
||||
|
||||
func NewNodeLabelForbiddenError(forbiddenSpec *capsulev1beta1.ForbiddenListSpec) error {
|
||||
func NewNodeLabelForbiddenError(forbiddenSpec *capsulev1beta2.ForbiddenListSpec) error {
|
||||
return &nodeLabelForbiddenError{
|
||||
spec: forbiddenSpec,
|
||||
}
|
||||
@@ -42,10 +42,10 @@ func (f nodeLabelForbiddenError) Error() string {
|
||||
}
|
||||
|
||||
type nodeAnnotationForbiddenError struct {
|
||||
spec *capsulev1beta1.ForbiddenListSpec
|
||||
spec *capsulev1beta2.ForbiddenListSpec
|
||||
}
|
||||
|
||||
func NewNodeAnnotationForbiddenError(forbiddenSpec *capsulev1beta1.ForbiddenListSpec) error {
|
||||
func NewNodeAnnotationForbiddenError(forbiddenSpec *capsulev1beta2.ForbiddenListSpec) error {
|
||||
return &nodeAnnotationForbiddenError{
|
||||
spec: forbiddenSpec,
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
utils2 "github.com/clastix/capsule/pkg/utils"
|
||||
capsuleutils "github.com/clastix/capsule/pkg/utils"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -62,7 +62,7 @@ func (h *handler) setOwnerRef(ctx context.Context, req admission.Request, client
|
||||
return &response
|
||||
}
|
||||
|
||||
ln, err := utils2.GetTypeLabel(&capsulev1beta1.Tenant{})
|
||||
ln, err := capsuleutils.GetTypeLabel(&capsulev1beta2.Tenant{})
|
||||
if err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
|
||||
@@ -71,7 +71,7 @@ func (h *handler) setOwnerRef(ctx context.Context, req admission.Request, client
|
||||
// If we already had TenantName label on NS -> assign to it
|
||||
if label, ok := ns.ObjectMeta.Labels[ln]; ok {
|
||||
// retrieving the selected Tenant
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
if err = client.Get(ctx, types.NamespacedName{Name: label}, tnt); err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
|
||||
@@ -96,7 +96,7 @@ func (h *handler) setOwnerRef(ctx context.Context, req admission.Request, client
|
||||
|
||||
// Find tenants belonging to user (it can be regular user or ServiceAccount)
|
||||
if strings.HasPrefix(req.UserInfo.Username, "system:serviceaccount:") {
|
||||
var tntList *capsulev1beta1.TenantList
|
||||
var tntList *capsulev1beta2.TenantList
|
||||
|
||||
if tntList, err = h.listTenantsForOwnerKind(ctx, "ServiceAccount", req.UserInfo.Username, client); err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
@@ -108,7 +108,7 @@ func (h *handler) setOwnerRef(ctx context.Context, req admission.Request, client
|
||||
tenants = append(tenants, tnt)
|
||||
}
|
||||
} else {
|
||||
var tntList *capsulev1beta1.TenantList
|
||||
var tntList *capsulev1beta2.TenantList
|
||||
|
||||
if tntList, err = h.listTenantsForOwnerKind(ctx, "User", req.UserInfo.Username, client); err != nil {
|
||||
response := admission.Errored(http.StatusBadRequest, err)
|
||||
@@ -170,9 +170,9 @@ func (h *handler) setOwnerRef(ctx context.Context, req admission.Request, client
|
||||
return &response
|
||||
}
|
||||
|
||||
func (h *handler) patchResponseForOwnerRef(tenant *capsulev1beta1.Tenant, ns *corev1.Namespace, recorder record.EventRecorder) admission.Response {
|
||||
func (h *handler) patchResponseForOwnerRef(tenant *capsulev1beta2.Tenant, ns *corev1.Namespace, recorder record.EventRecorder) admission.Response {
|
||||
scheme := runtime.NewScheme()
|
||||
_ = capsulev1beta1.AddToScheme(scheme)
|
||||
_ = capsulev1beta2.AddToScheme(scheme)
|
||||
_ = corev1.AddToScheme(scheme)
|
||||
|
||||
o, err := json.Marshal(ns.DeepCopy())
|
||||
@@ -196,8 +196,8 @@ func (h *handler) patchResponseForOwnerRef(tenant *capsulev1beta1.Tenant, ns *co
|
||||
return admission.PatchResponseFromRaw(o, c)
|
||||
}
|
||||
|
||||
func (h *handler) listTenantsForOwnerKind(ctx context.Context, ownerKind string, ownerName string, clt client.Client) (*capsulev1beta1.TenantList, error) {
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
func (h *handler) listTenantsForOwnerKind(ctx context.Context, ownerKind string, ownerName string, clt client.Client) (*capsulev1beta2.TenantList, error) {
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
fields := client.MatchingFields{
|
||||
".spec.owner.ownerkind": fmt.Sprintf("%s:%s", ownerKind, ownerName),
|
||||
}
|
||||
@@ -206,7 +206,7 @@ func (h *handler) listTenantsForOwnerKind(ctx context.Context, ownerKind string,
|
||||
return tntList, err
|
||||
}
|
||||
|
||||
type sortedTenants []capsulev1beta1.Tenant
|
||||
type sortedTenants []capsulev1beta2.Tenant
|
||||
|
||||
func (s sortedTenants) Len() int {
|
||||
return len(s)
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -30,7 +30,7 @@ func (h *containerRegistryHandler) OnCreate(c client.Client, decoder *admission.
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
if err := c.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", pod.Namespace),
|
||||
}); err != nil {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -30,7 +30,7 @@ func (r *imagePullPolicy) OnCreate(c client.Client, decoder *admission.Decoder,
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
if err := c.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", pod.Namespace),
|
||||
}); err != nil {
|
||||
|
||||
@@ -6,7 +6,7 @@ package pod
|
||||
import (
|
||||
"strings"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
type PullPolicy interface {
|
||||
@@ -32,7 +32,7 @@ func (i imagePullPolicyValidator) AllowedPullPolicies() []string {
|
||||
return i.allowedPolicies
|
||||
}
|
||||
|
||||
func NewPullPolicy(tenant *capsulev1beta1.Tenant) PullPolicy {
|
||||
func NewPullPolicy(tenant *capsulev1beta2.Tenant) PullPolicy {
|
||||
// the Tenant doesn't enforce the allowed image pull policy, returning nil
|
||||
if len(tenant.Spec.ImagePullPolicies) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -30,7 +30,7 @@ func (h *priorityClass) OnCreate(c client.Client, decoder *admission.Decoder, re
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
|
||||
if err := c.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", pod.Namespace),
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -32,7 +32,7 @@ func (h *handler) OnCreate(c client.Client, decoder *admission.Decoder, recorder
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
if err := c.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", pvc.Namespace),
|
||||
}); err != nil {
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
)
|
||||
|
||||
// +kubebuilder:webhook:path=/tenants,mutating=false,sideEffects=None,admissionReviewVersions=v1,failurePolicy=fail,groups="capsule.clastix.io",resources=tenants,verbs=create;update;delete,versions=v1beta1,name=tenants.capsule.clastix.io
|
||||
// +kubebuilder:webhook:path=/tenants,mutating=false,sideEffects=None,admissionReviewVersions=v1,failurePolicy=fail,groups="capsule.clastix.io",resources=tenants,verbs=create;update;delete,versions=v1beta2,name=tenants.capsule.clastix.io
|
||||
|
||||
type tenant struct {
|
||||
handlers []capsulewebhook.Handler
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -31,7 +31,7 @@ func (r *handler) handleService(ctx context.Context, clt client.Client, decoder
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
if err := clt.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", svc.GetNamespace()),
|
||||
}); err != nil {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func ContainerRegistryRegexHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *containerRegistryRegexHandler) validate(decoder *admission.Decoder, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
@@ -31,7 +31,7 @@ func CordoningHandler(configuration configuration.Configuration) capsulewebhook.
|
||||
}
|
||||
|
||||
func (h *cordoningHandler) cordonHandler(ctx context.Context, clt client.Client, req admission.Request, recorder record.EventRecorder) *admission.Response {
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
|
||||
if err := clt.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", req.Namespace),
|
||||
@@ -44,7 +44,7 @@ func (h *cordoningHandler) cordonHandler(ctx context.Context, clt client.Client,
|
||||
}
|
||||
|
||||
tnt := tntList.Items[0]
|
||||
if tnt.IsCordoned() && utils.IsCapsuleUser(ctx, req, clt, h.configuration.UserGroups()) {
|
||||
if tnt.Spec.Cordoned && utils.IsCapsuleUser(ctx, req, clt, h.configuration.UserGroups()) {
|
||||
recorder.Eventf(&tnt, corev1.EventTypeWarning, "TenantFreezed", "%s %s/%s cannot be %sd, current Tenant is freezed", req.Kind.String(), req.Namespace, req.Name, strings.ToLower(string(req.Operation)))
|
||||
|
||||
response := admission.Denied(fmt.Sprintf("tenant %s is freezed: please, reach out to the system administrator", tnt.GetName()))
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -36,7 +36,7 @@ func ResourceCounterHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (r *resourceCounterHandler) getTenantName(ctx context.Context, clt client.Client, req admission.Request) (string, error) {
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
tntList := &capsulev1beta2.TenantList{}
|
||||
|
||||
if err := clt.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".status.namespaces", req.Namespace),
|
||||
@@ -67,7 +67,7 @@ func (r *resourceCounterHandler) OnCreate(clt client.Client, decoder *admission.
|
||||
|
||||
kgv := fmt.Sprintf("%s.%s_%s", req.Resource.Resource, req.Resource.Group, req.Resource.Version)
|
||||
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
|
||||
var limit int64
|
||||
|
||||
@@ -76,20 +76,20 @@ func (r *resourceCounterHandler) OnCreate(clt client.Client, decoder *admission.
|
||||
return retryErr
|
||||
}
|
||||
|
||||
if limit, retryErr = capsulev1beta1.GetLimitResourceFromTenant(*tnt, kgv); retryErr != nil {
|
||||
if errors.As(err, &capsulev1beta1.NonLimitedResourceError{}) {
|
||||
if limit, retryErr = capsulev1beta2.GetLimitResourceFromTenant(*tnt, kgv); retryErr != nil {
|
||||
if errors.As(err, &capsulev1beta2.NonLimitedResourceError{}) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
used, _ := capsulev1beta1.GetUsedResourceFromTenant(*tnt, kgv)
|
||||
used, _ := capsulev1beta2.GetUsedResourceFromTenant(*tnt, kgv)
|
||||
|
||||
if used >= limit {
|
||||
return NewCustomResourceQuotaError(kgv, limit)
|
||||
}
|
||||
|
||||
tnt.Annotations[capsulev1beta1.UsedAnnotationForResource(kgv)] = fmt.Sprintf("%d", used+1)
|
||||
tnt.Annotations[capsulev1beta2.UsedAnnotationForResource(kgv)] = fmt.Sprintf("%d", used+1)
|
||||
|
||||
return clt.Update(ctx, tnt)
|
||||
})
|
||||
@@ -122,7 +122,7 @@ func (r *resourceCounterHandler) OnDelete(clt client.Client, decoder *admission.
|
||||
kgv := fmt.Sprintf("%s.%s_%s", req.Resource.Resource, req.Resource.Group, req.Resource.Version)
|
||||
|
||||
err = retry.RetryOnConflict(retry.DefaultRetry, func() (retryErr error) {
|
||||
tnt := &capsulev1beta1.Tenant{}
|
||||
tnt := &capsulev1beta2.Tenant{}
|
||||
if retryErr = clt.Get(ctx, types.NamespacedName{Name: tntName}, tnt); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -131,13 +131,13 @@ func (r *resourceCounterHandler) OnDelete(clt client.Client, decoder *admission.
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := tnt.Annotations[capsulev1beta1.UsedAnnotationForResource(kgv)]; !ok {
|
||||
if _, ok := tnt.Annotations[capsulev1beta2.UsedAnnotationForResource(kgv)]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
used, _ := capsulev1beta1.GetUsedResourceFromTenant(*tnt, kgv)
|
||||
used, _ := capsulev1beta2.GetUsedResourceFromTenant(*tnt, kgv)
|
||||
|
||||
tnt.Annotations[capsulev1beta1.UsedAnnotationForResource(kgv)] = fmt.Sprintf("%d", used-1)
|
||||
tnt.Annotations[capsulev1beta2.UsedAnnotationForResource(kgv)] = fmt.Sprintf("%d", used-1)
|
||||
|
||||
return clt.Update(ctx, tnt)
|
||||
})
|
||||
|
||||
@@ -5,13 +5,14 @@ package tenant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"k8s.io/client-go/tools/record"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -23,23 +24,23 @@ func ForbiddenAnnotationsRegexHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *forbiddenAnnotationsRegexHandler) validate(decoder *admission.Decoder, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
if tenant.Annotations == nil {
|
||||
if tenant.Spec.NamespaceOptions == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
annotationsToCheck := []string{
|
||||
capsulev1beta1.ForbiddenNamespaceAnnotationsRegexpAnnotation,
|
||||
capsulev1beta1.ForbiddenNamespaceLabelsRegexpAnnotation,
|
||||
annotationsToCheck := map[string]string{
|
||||
"labels": tenant.Spec.NamespaceOptions.ForbiddenLabels.Regex,
|
||||
"annotations": tenant.Spec.NamespaceOptions.ForbiddenAnnotations.Regex,
|
||||
}
|
||||
|
||||
for _, annotation := range annotationsToCheck {
|
||||
if _, err := regexp.Compile(tenant.Annotations[annotation]); err != nil {
|
||||
response := admission.Denied("unable to compile " + annotation + " regex annotation")
|
||||
for scope, annotation := range annotationsToCheck {
|
||||
if _, err := regexp.Compile(tenant.Spec.NamespaceOptions.ForbiddenLabels.Regex); err != nil {
|
||||
response := admission.Denied(fmt.Sprintf("unable to compile %s regex for forbidden %s", annotation, scope))
|
||||
|
||||
return &response
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -36,20 +36,20 @@ func (h *freezedEmitterHandler) OnDelete(client.Client, *admission.Decoder, reco
|
||||
|
||||
func (h *freezedEmitterHandler) OnUpdate(_ client.Client, decoder *admission.Decoder, recorder record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
oldTnt := &capsulev1beta1.Tenant{}
|
||||
oldTnt := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.DecodeRaw(req.OldObject, oldTnt); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
newTnt := &capsulev1beta1.Tenant{}
|
||||
newTnt := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, newTnt); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case !oldTnt.IsCordoned() && newTnt.IsCordoned():
|
||||
case !oldTnt.Spec.Cordoned && newTnt.Spec.Cordoned:
|
||||
recorder.Eventf(newTnt, corev1.EventTypeNormal, "TenantCordoned", "Tenant has been cordoned")
|
||||
case oldTnt.IsCordoned() && !newTnt.IsCordoned():
|
||||
case oldTnt.Spec.Cordoned && !newTnt.Spec.Cordoned:
|
||||
recorder.Eventf(newTnt, corev1.EventTypeNormal, "TenantUncordoned", "Tenant has been uncordoned")
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func HostnameRegexHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *hostnameRegexHandler) validate(decoder *admission.Decoder, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func IngressClassRegexHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *ingressClassRegexHandler) validate(decoder *admission.Decoder, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func NameHandler() capsulewebhook.Handler {
|
||||
|
||||
func (h *nameHandler) OnCreate(_ client.Client, decoder *admission.Decoder, _ record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -5,14 +5,13 @@ package tenant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -31,14 +30,14 @@ func (h *protectedHandler) OnCreate(client.Client, *admission.Decoder, record.Ev
|
||||
|
||||
func (h *protectedHandler) OnDelete(clt client.Client, decoder *admission.Decoder, _ record.EventRecorder) capsulewebhook.Func {
|
||||
return func(ctx context.Context, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
|
||||
if err := clt.Get(ctx, types.NamespacedName{Name: req.AdmissionRequest.Name}, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
if _, protected := tenant.Annotations[capsulev1beta1.ProtectedTenantAnnotation]; protected {
|
||||
response := admission.Denied(fmt.Sprintf("tenant is protected and cannot be deleted, remove %s annotation before proceeding", capsulev1beta1.ProtectedTenantAnnotation))
|
||||
if tenant.Spec.PreventDeletion {
|
||||
response := admission.Denied("tenant is protected and cannot be deleted")
|
||||
|
||||
return &response
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ func RoleBindingRegexHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *rbRegexHandler) validate(req admission.Request, decoder *admission.Decoder) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func ServiceAccountNameHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *saNameHandler) validateServiceAccountName(req admission.Request, decoder *admission.Decoder) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
)
|
||||
@@ -24,7 +24,7 @@ func StorageClassRegexHandler() capsulewebhook.Handler {
|
||||
}
|
||||
|
||||
func (h *storageClassRegexHandler) validate(decoder *admission.Decoder, req admission.Request) *admission.Response {
|
||||
tenant := &capsulev1beta1.Tenant{}
|
||||
tenant := &capsulev1beta2.Tenant{}
|
||||
if err := decoder.Decode(req, tenant); err != nil {
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
"github.com/clastix/capsule/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -31,7 +31,7 @@ func IsCapsuleUser(ctx context.Context, req admission.Request, clt client.Client
|
||||
targetNamespace := parts[2]
|
||||
|
||||
if len(targetNamespace) > 0 {
|
||||
tl := &capsulev1beta1.TenantList{}
|
||||
tl := &capsulev1beta2.TenantList{}
|
||||
if err := clt.List(ctx, tl, client.MatchingFieldsSelector{Selector: fields.OneTermEqualSelector(".status.namespaces", targetNamespace)}); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -6,17 +6,17 @@ package utils
|
||||
import (
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
capsulev1beta2 "github.com/clastix/capsule/api/v1beta2"
|
||||
)
|
||||
|
||||
func IsTenantOwner(owners capsulev1beta1.OwnerListSpec, userInfo authenticationv1.UserInfo) bool {
|
||||
func IsTenantOwner(owners capsulev1beta2.OwnerListSpec, userInfo authenticationv1.UserInfo) bool {
|
||||
for _, owner := range owners {
|
||||
switch owner.Kind {
|
||||
case capsulev1beta1.UserOwner, capsulev1beta1.ServiceAccountOwner:
|
||||
case capsulev1beta2.UserOwner, capsulev1beta2.ServiceAccountOwner:
|
||||
if userInfo.Username == owner.Name {
|
||||
return true
|
||||
}
|
||||
case capsulev1beta1.GroupOwner:
|
||||
case capsulev1beta2.GroupOwner:
|
||||
for _, group := range userInfo.Groups {
|
||||
if group == owner.Name {
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user