Skip to content

Commit ce8a1ce

Browse files
authored
Merge pull request #704 from jakobmoellerdev/remove-service-accounts
chore!: remove service account spec and impersonation
2 parents 7c68a22 + ac1fe1c commit ce8a1ce

File tree

7 files changed

+10
-164
lines changed

7 files changed

+10
-164
lines changed

api/v1alpha1/resourcegraphdefinition_types.go

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,7 @@ package v1alpha1
1616
import (
1717
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1818
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19-
runtime "k8s.io/apimachinery/pkg/runtime"
20-
)
21-
22-
const (
23-
// DefaultServiceAccountKey is the key to use for the default service account
24-
// in the serviceAccounts map.
25-
DefaultServiceAccountKey = "*"
19+
"k8s.io/apimachinery/pkg/runtime"
2620
)
2721

2822
// ResourceGraphDefinitionSpec defines the desired state of ResourceGraphDefinition
@@ -37,13 +31,6 @@ type ResourceGraphDefinitionSpec struct {
3731
//
3832
// +kubebuilder:validation:Optional
3933
Resources []*Resource `json:"resources,omitempty"`
40-
// ServiceAccount configuration for controller impersonation.
41-
// Key is the namespace, value is the service account name to use.
42-
// Special key "*" defines the default service account for any
43-
// namespace not explicitly mapped.
44-
//
45-
// +kubebuilder:validation:Optional
46-
DefaultServiceAccounts map[string]string `json:"defaultServiceAccounts,omitempty"`
4734
}
4835

4936
// Schema represents the attributes that define an instance of
@@ -198,7 +185,7 @@ func (o *ResourceGraphDefinition) SetConditions(conditions []Condition) {
198185
o.Status.Conditions = conditions
199186
}
200187

201-
//+kubebuilder:object:root=true
188+
// +kubebuilder:object:root=true
202189

203190
// ResourceGraphDefinitionList contains a list of ResourceGraphDefinition
204191
type ResourceGraphDefinitionList struct {

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 0 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/kro.run_resourcegraphdefinitions.yaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,6 @@ spec:
6060
description: ResourceGraphDefinitionSpec defines the desired state of
6161
ResourceGraphDefinition
6262
properties:
63-
defaultServiceAccounts:
64-
additionalProperties:
65-
type: string
66-
description: |-
67-
ServiceAccount configuration for controller impersonation.
68-
Key is the namespace, value is the service account name to use.
69-
Special key "*" defines the default service account for any
70-
namespace not explicitly mapped.
71-
type: object
7263
resources:
7364
description: The resources that are part of the resourcegraphdefinition.
7465
items:

helm/crds/kro.run_resourcegraphdefinitions.yaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,6 @@ spec:
6060
description: ResourceGraphDefinitionSpec defines the desired state of
6161
ResourceGraphDefinition
6262
properties:
63-
defaultServiceAccounts:
64-
additionalProperties:
65-
type: string
66-
description: |-
67-
ServiceAccount configuration for controller impersonation.
68-
Key is the namespace, value is the service account name to use.
69-
Special key "*" defines the default service account for any
70-
namespace not explicitly mapped.
71-
type: object
7263
resources:
7364
description: The resources that are part of the resourcegraphdefinition.
7465
items:

pkg/controller/instance/controller.go

Lines changed: 7 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@ import (
2121
"time"
2222

2323
"github.com/go-logr/logr"
24-
"github.com/prometheus/client_golang/prometheus"
2524
apierrors "k8s.io/apimachinery/pkg/api/errors"
2625
"k8s.io/apimachinery/pkg/api/meta"
2726
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2827
"k8s.io/apimachinery/pkg/runtime/schema"
29-
"k8s.io/client-go/dynamic"
3028
ctrl "sigs.k8s.io/controller-runtime"
3129

32-
"github.com/kro-run/kro/api/v1alpha1"
3330
kroclient "github.com/kro-run/kro/pkg/client"
3431
"github.com/kro-run/kro/pkg/graph"
3532
"github.com/kro-run/kro/pkg/metadata"
@@ -88,8 +85,6 @@ type Controller struct {
8885
// reconcileConfig holds the configuration parameters for the reconciliation
8986
// process.
9087
reconcileConfig ReconcileConfig
91-
// defaultServiceAccounts is a map of service accounts to use for controller impersonation.
92-
defaultServiceAccounts map[string]string
9388
}
9489

9590
// NewController creates a new Controller instance.
@@ -100,17 +95,15 @@ func NewController(
10095
rgd *graph.Graph,
10196
clientSet kroclient.SetInterface,
10297
restMapper meta.RESTMapper,
103-
defaultServiceAccounts map[string]string,
10498
instanceLabeler metadata.Labeler,
10599
) *Controller {
106100
return &Controller{
107-
log: log,
108-
gvr: gvr,
109-
clientSet: clientSet,
110-
rgd: rgd,
111-
instanceLabeler: instanceLabeler,
112-
reconcileConfig: reconcileConfig,
113-
defaultServiceAccounts: defaultServiceAccounts,
101+
log: log,
102+
gvr: gvr,
103+
clientSet: clientSet,
104+
rgd: rgd,
105+
instanceLabeler: instanceLabeler,
106+
reconcileConfig: reconcileConfig,
114107
}
115108
}
116109

@@ -145,17 +138,10 @@ func (c *Controller) Reconcile(ctx context.Context, req ctrl.Request) error {
145138
return fmt.Errorf("failed to create instance sub-resources labeler: %w", err)
146139
}
147140

148-
// If possible, use a service account to create the execution client
149-
// TODO(a-hilaly): client caching
150-
executionClient, err := c.getExecutionClient(namespace)
151-
if err != nil {
152-
return fmt.Errorf("failed to create execution client: %w", err)
153-
}
154-
155141
instanceGraphReconciler := &instanceGraphReconciler{
156142
log: log,
157143
gvr: c.gvr,
158-
client: executionClient,
144+
client: c.clientSet.Dynamic(),
159145
restMapper: c.clientSet.RESTMapper(),
160146
runtime: rgRuntime,
161147
instanceLabeler: c.instanceLabeler,
@@ -177,98 +163,3 @@ func getNamespaceName(req ctrl.Request) (string, string) {
177163
}
178164
return namespace, name
179165
}
180-
181-
// errorCategory helps classify different types of impersonation errors
182-
type errorCategory string
183-
184-
const (
185-
errorConfigCreate errorCategory = "config_create"
186-
errorInvalidSA errorCategory = "invalid_sa"
187-
errorClientCreate errorCategory = "client_create"
188-
errorPermissions errorCategory = "permissions"
189-
)
190-
191-
// getExecutionClient determines the execution client to use for the instance.
192-
// If the instance is created in a namespace of which a service account is specified,
193-
// the execution client will be created using the service account. If no service account
194-
// is specified for the namespace, the default client will be used.
195-
func (c *Controller) getExecutionClient(namespace string) (dynamic.Interface, error) {
196-
// if no service accounts are specified, use the default client
197-
if len(c.defaultServiceAccounts) == 0 {
198-
c.log.V(1).Info("no service accounts configured, using default client")
199-
return c.clientSet.Dynamic(), nil
200-
}
201-
202-
timer := prometheus.NewTimer(impersonationDuration.WithLabelValues(namespace, ""))
203-
defer timer.ObserveDuration()
204-
205-
// Check for namespace specific service account
206-
if sa, ok := c.defaultServiceAccounts[namespace]; ok {
207-
userName, err := getServiceAccountUserName(namespace, sa)
208-
if err != nil {
209-
c.handleImpersonateError(namespace, sa, err)
210-
return nil, fmt.Errorf("invalid service account configuration: %w", err)
211-
}
212-
213-
pivotedClient, err := c.clientSet.WithImpersonation(userName)
214-
if err != nil {
215-
c.handleImpersonateError(namespace, sa, err)
216-
return nil, fmt.Errorf("failed to create impersonated client: %w", err)
217-
}
218-
219-
impersonationTotal.WithLabelValues(namespace, sa, "success").Inc()
220-
return pivotedClient.Dynamic(), nil
221-
}
222-
223-
// Check for default service account (marked by "*")
224-
if defaultSA, ok := c.defaultServiceAccounts[v1alpha1.DefaultServiceAccountKey]; ok {
225-
userName, err := getServiceAccountUserName(namespace, defaultSA)
226-
if err != nil {
227-
c.handleImpersonateError(namespace, defaultSA, err)
228-
return nil, fmt.Errorf("invalid default service account configuration: %w", err)
229-
}
230-
231-
pivotedClient, err := c.clientSet.WithImpersonation(userName)
232-
if err != nil {
233-
c.handleImpersonateError(namespace, defaultSA, err)
234-
return nil, fmt.Errorf("failed to create impersonated client with default SA: %w", err)
235-
}
236-
237-
impersonationTotal.WithLabelValues(namespace, defaultSA, "success").Inc()
238-
return pivotedClient.Dynamic(), nil
239-
}
240-
241-
impersonationTotal.WithLabelValues(namespace, "", "default").Inc()
242-
// Fallback to the default client
243-
return c.clientSet.Dynamic(), nil
244-
}
245-
246-
// handleImpersonateError logs the error and records the error in the metrics
247-
func (c *Controller) handleImpersonateError(namespace, sa string, err error) {
248-
var category errorCategory
249-
switch {
250-
case strings.Contains(err.Error(), "forbidden"):
251-
category = errorPermissions
252-
case strings.Contains(err.Error(), "cannot get token"):
253-
category = errorConfigCreate
254-
default:
255-
category = errorClientCreate
256-
}
257-
recordImpersonateError(namespace, sa, category)
258-
c.log.Error(
259-
err,
260-
"failed to create impersonated client",
261-
"namespace", namespace,
262-
"serviceAccount", sa,
263-
"errorCategory", category,
264-
)
265-
}
266-
267-
// getServiceAccountUserName builds the impersonate service account user name.
268-
// The format of the user name is "system:serviceaccount:<namespace>:<serviceaccount>"
269-
func getServiceAccountUserName(namespace, serviceAccount string) (string, error) {
270-
if namespace == "" || serviceAccount == "" {
271-
return "", fmt.Errorf("namespace and service account must be provided")
272-
}
273-
return fmt.Sprintf("system:serviceaccount:%s:%s", namespace, serviceAccount), nil
274-
}

pkg/controller/instance/metrics.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ var (
5757
)
5858
)
5959

60-
func recordImpersonateError(namespace, sa string, category errorCategory) {
61-
impersonationErrors.WithLabelValues(namespace, sa, string(category)).Inc()
62-
}
63-
6460
func init() {
6561
metrics.Registry.MustRegister(
6662
impersonationTotal,

pkg/controller/resourcegraphdefinition/controller_reconcile.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ func (r *ResourceGraphDefinitionReconciler) reconcileResourceGraphDefinition(
7474

7575
// Setup and start microcontroller
7676
gvr := processedRGD.Instance.GetGroupVersionResource()
77-
controller := r.setupMicroController(gvr, processedRGD,
78-
rgd.Spec.DefaultServiceAccounts, graphExecLabeler)
77+
controller := r.setupMicroController(gvr, processedRGD, graphExecLabeler)
7978

8079
log.V(1).Info("reconciling resource graph definition micro controller")
8180
// TODO: the context that is passed here is tied to the reconciliation of the rgd, we might need to make
@@ -100,7 +99,6 @@ func (r *ResourceGraphDefinitionReconciler) setupLabeler(rgd *v1alpha1.ResourceG
10099
func (r *ResourceGraphDefinitionReconciler) setupMicroController(
101100
gvr schema.GroupVersionResource,
102101
processedRGD *graph.Graph,
103-
defaultSVCs map[string]string,
104102
labeler metadata.Labeler,
105103
) *instancectrl.Controller {
106104
instanceLogger := r.instanceLogger.WithName(fmt.Sprintf("%s-controller", gvr.Resource)).WithValues(
@@ -120,7 +118,6 @@ func (r *ResourceGraphDefinitionReconciler) setupMicroController(
120118
processedRGD,
121119
r.clientSet,
122120
r.clientSet.RESTMapper(),
123-
defaultSVCs,
124121
labeler,
125122
)
126123
}

0 commit comments

Comments
 (0)