Skip to content
Closed
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ ifeq ($(CAPSULE_PROXY_MODE),http)
--set "serviceMonitor.enabled=false" \
--set "options.generateCertificates=false" \
--set "certManager.generateCertificates=false" \
--set "options.extraArgs={--feature-gates=ProxyAllNamespaced=true}"
--set "options.extraArgs={--feature-gates=ProxyClusterScoped=true,--feature-gates=ProxyAllNamespaced=true}"
else
@echo "Running in HTTPS mode"
@echo "Installing Capsule-Proxy using HELM..."
Expand All @@ -206,7 +206,7 @@ else
--set "serviceMonitor.enabled=false" \
--set "options.generateCertificates=false" \
--set "certManager.certificate.ipAddresses={127.0.0.1}" \
--set "options.extraArgs={--feature-gates=ProxyAllNamespaced=true}"
--set "options.extraArgs={--feature-gates=ProxyClusterScoped=true,--feature-gates=ProxyAllNamespaced=true}"
endif
@kubectl rollout restart ds capsule-proxy -n capsule-system || true
$(MAKE) generate-kubeconfigs
Expand Down
6 changes: 2 additions & 4 deletions api/v1beta1/proxysettings_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ type OwnerSpec struct {
Kind capsuleapi.OwnerKind `json:"kind"`
// Name of tenant owner.
Name string `json:"name"`
// Cluster Resources for tenant Owner.
ClusterResources []ClusterResource `json:"clusterResources,omitempty"`
// Deprecated: Use Global Proxy Settings instead (https://projectcapsule.dev/docs/proxy/proxysettings/#globalproxysettings)
//
// Proxy settings for tenant owner.
ProxyOperations []capsuleapi.ProxySettings `json:"proxySettings,omitempty"`
// Cluster Resources for tenant Owner.
ClusterResources []ClusterResource `json:"clusterResources,omitempty"`
}

// ProxySettingSpec defines the additional Capsule Proxy settings for additional users of the Tenant.
Expand Down
12 changes: 6 additions & 6 deletions api/v1beta1/zz_generated.deepcopy.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 @@ -142,10 +142,7 @@ spec:
description: Name of tenant owner.
type: string
proxySettings:
description: |-
Deprecated: Use Global Proxy Settings instead (https://projectcapsule.dev/docs/proxy/proxysettings/#globalproxysettings)

Proxy settings for tenant owner.
description: Proxy settings for tenant owner.
items:
properties:
kind:
Expand Down
13 changes: 10 additions & 3 deletions internal/authorization/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/projectcapsule/capsule-proxy/internal/tenant"
)

func MutateAuthorization(proxyTenants []*tenant.ProxyTenant, obj *runtime.Object, gvk schema.GroupVersionKind) error {
func MutateAuthorization(proxyClusterScoped bool, proxyTenants []*tenant.ProxyTenant, obj *runtime.Object, gvk schema.GroupVersionKind) error {
switch gvk.Kind {
case "SelfSubjectAccessReview":
//nolint:forcetypeassert
Expand All @@ -21,6 +21,10 @@ func MutateAuthorization(proxyTenants []*tenant.ProxyTenant, obj *runtime.Object
accessReview.Status.Allowed = true
}

if !proxyClusterScoped {
return nil
}

accessReviewGvk := schema.GroupVersionKind{
Group: accessReview.Spec.ResourceAttributes.Group,
Version: accessReview.Spec.ResourceAttributes.Version,
Expand All @@ -44,8 +48,11 @@ func MutateAuthorization(proxyTenants []*tenant.ProxyTenant, obj *runtime.Object
rules := (*obj).(*authorizationv1.SelfSubjectRulesReview)

var resourceRules []authorizationv1.ResourceRule

resourceRules = getAllResourceRules(proxyTenants)
if proxyClusterScoped {
resourceRules = getAllResourceRules(proxyTenants)
} else {
resourceRules = []authorizationv1.ResourceRule{}
}

resourceRules = append(resourceRules, authorizationv1.ResourceRule{
APIGroups: []string{""},
Expand Down
3 changes: 1 addition & 2 deletions internal/features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ const (
// essentially bypassing any authorization. Only use this option in trusted environments
// where authorization/authentication is offloaded to external systems.
SkipImpersonationReview = "SkipImpersonationReview"
// Deprecated: Use Global Proxy Settings instead (https://projectcapsule.dev/docs/proxy/proxysettings/#globalproxysettings)
//

// ProxyClusterScoped allows to proxy all clusterScoped objects
// for all tenant users.
ProxyClusterScoped = "ProxyClusterScoped"
Expand Down
42 changes: 0 additions & 42 deletions internal/indexer/tenant_owner.go

This file was deleted.

95 changes: 95 additions & 0 deletions internal/modules/ingressclass/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2020-2025 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package ingressclass

import (
"net/http"

"github.com/go-logr/logr"
"github.com/gorilla/mux"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/projectcapsule/capsule-proxy/internal/modules"
"github.com/projectcapsule/capsule-proxy/internal/modules/errors"
"github.com/projectcapsule/capsule-proxy/internal/modules/utils"
"github.com/projectcapsule/capsule-proxy/internal/request"
"github.com/projectcapsule/capsule-proxy/internal/tenant"
)

type get struct {
client client.Reader
log logr.Logger
gk schema.GroupVersionKind
}

func Get(client client.Reader) modules.Module {
return &get{
client: client,
log: ctrl.Log.WithName("ingressclass_get"),
gk: schema.GroupVersionKind{
Group: networkingv1.GroupName,
Version: "*",
Kind: "ingressclasses",
},
}
}

func (g get) GroupVersionKind() schema.GroupVersionKind {
return g.gk
}

func (g get) GroupKind() schema.GroupKind {
return g.gk.GroupKind()
}

func (g get) Path() string {
return "/apis/networking.k8s.io/{version}/{endpoint:ingressclasses}/{name}"
}

func (g get) Methods() []string {
return []string{}
}

func (g get) Handle(proxyTenants []*tenant.ProxyTenant, proxyRequest request.Request) (selector labels.Selector, err error) {
httpRequest := proxyRequest.GetHTTPRequest()

name := mux.Vars(httpRequest)["name"]

_, exactMatch, regexMatch, requirements := getIngressClasses(httpRequest, proxyTenants)
if len(requirements) > 0 {
ic, errIc := getIngressClassFromRequest(httpRequest)
if errIc != nil {
return nil, errors.NewBadRequest(errIc, g.GroupKind())
}

return utils.HandleGetSelector(httpRequest.Context(), ic, g.client, requirements, name, g.GroupKind())
}

icl, err := getIngressClassListFromRequest(httpRequest)
if err != nil {
return nil, errors.NewBadRequest(err, g.GroupKind())
}

if err = g.client.List(httpRequest.Context(), icl, client.MatchingLabels{corev1.LabelMetadataName: name}); err != nil {
return nil, errors.NewBadRequest(err, g.GroupKind())
}

var r *labels.Requirement

if r, err = getIngressClassSelector(icl, exactMatch, regexMatch); err == nil {
return labels.NewSelector().Add(*r), nil
}

switch httpRequest.Method {
case http.MethodGet:
return nil, errors.NewNotFoundError(name, g.GroupKind())
default:
return nil, nil
}
}
84 changes: 84 additions & 0 deletions internal/modules/ingressclass/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2020-2025 Project Capsule Authors
// SPDX-License-Identifier: Apache-2.0

package ingressclass

import (
"github.com/go-logr/logr"
networkingv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/selection"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/projectcapsule/capsule-proxy/internal/modules"
"github.com/projectcapsule/capsule-proxy/internal/modules/errors"
"github.com/projectcapsule/capsule-proxy/internal/modules/utils"
"github.com/projectcapsule/capsule-proxy/internal/request"
"github.com/projectcapsule/capsule-proxy/internal/tenant"
)

type list struct {
client client.Reader
log logr.Logger
gk schema.GroupVersionKind
}

func List(client client.Reader) modules.Module {
return &list{
client: client,
log: ctrl.Log.WithName("ingressclass_list"),
gk: schema.GroupVersionKind{
Group: networkingv1.GroupName,
Version: "*",
Kind: "ingressclasses",
},
}
}

func (l list) GroupVersionKind() schema.GroupVersionKind {
return l.gk
}

func (l list) GroupKind() schema.GroupKind {
return l.gk.GroupKind()
}

func (l list) Path() string {
return "/apis/networking.k8s.io/{version}/{endpoint:ingressclasses/?}"
}

func (l list) Methods() []string {
return []string{}
}

func (l list) Handle(proxyTenants []*tenant.ProxyTenant, proxyRequest request.Request) (selector labels.Selector, err error) {
httpRequest := proxyRequest.GetHTTPRequest()

allowed, exactMatch, regexMatch, selectorsMatch := getIngressClasses(httpRequest, proxyTenants)
if len(selectorsMatch) > 0 {
return utils.HandleListSelector(selectorsMatch)
}

icl, err := getIngressClassListFromRequest(httpRequest)
if err != nil {
return nil, errors.NewBadRequest(err, l.GroupKind())
}

if err = l.client.List(httpRequest.Context(), icl); err != nil {
return nil, errors.NewBadRequest(err, l.GroupKind())
}

var r *labels.Requirement

if r, err = getIngressClassSelector(icl, exactMatch, regexMatch); err != nil {
if !allowed {
return nil, errors.NewNotAllowed(l.GroupKind())
}

r, _ = labels.NewRequirement("dontexistsignoreme", selection.Exists, []string{})
}

return labels.NewSelector().Add(*r), nil
}
Loading
Loading