@@ -29,6 +29,7 @@ import (
29
29
"github.com/spf13/pflag"
30
30
colfeaturegate "go.opentelemetry.io/collector/featuregate"
31
31
networkingv1 "k8s.io/api/networking/v1"
32
+ rbacv1 "k8s.io/api/rbac/v1"
32
33
k8sruntime "k8s.io/apimachinery/pkg/runtime"
33
34
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
34
35
"k8s.io/client-go/kubernetes"
@@ -134,7 +135,7 @@ func main() {
134
135
pflag .BoolVar (& enableLeaderElection , "enable-leader-election" , false ,
135
136
"Enable leader election for controller manager. " +
136
137
"Enabling this will ensure there is only one active controller manager." )
137
- pflag .BoolVar (& createRBACPermissions , "create-rbac-permissions" , false , "Automatically create RBAC permissions needed by the processors" )
138
+ pflag .BoolVar (& createRBACPermissions , "create-rbac-permissions" , false , "Automatically create RBAC permissions needed by the processors (deprecated) " )
138
139
pflag .BoolVar (& enableMultiInstrumentation , "enable-multi-instrumentation" , false , "Controls whether the operator supports multi instrumentation" )
139
140
pflag .BoolVar (& enableApacheHttpdInstrumentation , constants .FlagApacheHttpd , true , "Controls whether the operator supports Apache HTTPD auto-instrumentation" )
140
141
pflag .BoolVar (& enableDotNetInstrumentation , constants .FlagDotNet , true , "Controls whether the operator supports dotnet auto-instrumentation" )
@@ -188,54 +189,6 @@ func main() {
188
189
189
190
restConfig := ctrl .GetConfigOrDie ()
190
191
191
- // builds the operator's configuration
192
- ad , err := autodetect .New (restConfig )
193
- if err != nil {
194
- setupLog .Error (err , "failed to setup auto-detect routine" )
195
- os .Exit (1 )
196
- }
197
-
198
- cfg := config .New (
199
- config .WithLogger (ctrl .Log .WithName ("config" )),
200
- config .WithVersion (v ),
201
- config .WithCollectorImage (collectorImage ),
202
- config .WithCreateRBACPermissions (createRBACPermissions ),
203
- config .WithEnableMultiInstrumentation (enableMultiInstrumentation ),
204
- config .WithEnableApacheHttpdInstrumentation (enableApacheHttpdInstrumentation ),
205
- config .WithEnableDotNetInstrumentation (enableDotNetInstrumentation ),
206
- config .WithEnableNginxInstrumentation (enableNginxInstrumentation ),
207
- config .WithEnablePythonInstrumentation (enablePythonInstrumentation ),
208
- config .WithTargetAllocatorImage (targetAllocatorImage ),
209
- config .WithOperatorOpAMPBridgeImage (operatorOpAMPBridgeImage ),
210
- config .WithAutoInstrumentationJavaImage (autoInstrumentationJava ),
211
- config .WithAutoInstrumentationNodeJSImage (autoInstrumentationNodeJS ),
212
- config .WithAutoInstrumentationPythonImage (autoInstrumentationPython ),
213
- config .WithAutoInstrumentationDotNetImage (autoInstrumentationDotNet ),
214
- config .WithAutoInstrumentationGoImage (autoInstrumentationGo ),
215
- config .WithAutoInstrumentationApacheHttpdImage (autoInstrumentationApacheHttpd ),
216
- config .WithAutoInstrumentationNginxImage (autoInstrumentationNginx ),
217
- config .WithAutoDetect (ad ),
218
- config .WithLabelFilters (labelsFilter ),
219
- config .WithAnnotationFilters (annotationsFilter ),
220
- )
221
- err = cfg .AutoDetect ()
222
- if err != nil {
223
- setupLog .Error (err , "failed to autodetect config variables" )
224
- }
225
- // Only add these to the scheme if they are available
226
- if cfg .PrometheusCRAvailability () == prometheus .Available {
227
- setupLog .Info ("Prometheus CRDs are installed, adding to scheme." )
228
- utilruntime .Must (monitoringv1 .AddToScheme (scheme ))
229
- } else {
230
- setupLog .Info ("Prometheus CRDs are not installed, skipping adding to scheme." )
231
- }
232
- if cfg .OpenShiftRoutesAvailability () == openshift .RoutesAvailable {
233
- setupLog .Info ("Openshift CRDs are installed, adding to scheme." )
234
- utilruntime .Must (routev1 .Install (scheme ))
235
- } else {
236
- setupLog .Info ("Openshift CRDs are not installed, skipping adding to scheme." )
237
- }
238
-
239
192
var namespaces map [string ]cache.Config
240
193
watchNamespace , found := os .LookupEnv ("WATCH_NAMESPACE" )
241
194
if found {
@@ -284,17 +237,81 @@ func main() {
284
237
os .Exit (1 )
285
238
}
286
239
240
+ clientset , clientErr := kubernetes .NewForConfig (mgr .GetConfig ())
241
+ if err != nil {
242
+ setupLog .Error (clientErr , "failed to create kubernetes clientset" )
243
+ }
244
+
245
+ reviewer := rbac .NewReviewer (clientset )
246
+ createRBACPermissions = true
287
247
ctx := ctrl .SetupSignalHandler ()
288
- err = addDependencies ( ctx , mgr , cfg , v )
248
+ w , err := checkRbacPermissions ( reviewer , ctx )
289
249
if err != nil {
290
- setupLog .Error (err , "failed to add/run bootstrap dependencies to the controller manager" )
250
+ createRBACPermissions = false
251
+ setupLog .Info ("the operator has not permissions to create rbac resources" , "error" , err , "serviceAccount" )
252
+ }
253
+ if w != nil {
254
+ createRBACPermissions = false
255
+ setupLog .Info ("the operator has not permissions to create rbac resources" , "permissions" , w )
256
+ }
257
+
258
+ if createRBACPermissions {
259
+ setupLog .Info ("the operator has permissions to create rbac resources" )
260
+ }
261
+
262
+ // builds the operator's configuration
263
+ ad , err := autodetect .New (restConfig )
264
+ if err != nil {
265
+ setupLog .Error (err , "failed to setup auto-detect routine" )
291
266
os .Exit (1 )
292
267
}
293
- clientset , clientErr := kubernetes .NewForConfig (mgr .GetConfig ())
268
+
269
+ cfg := config .New (
270
+ config .WithLogger (ctrl .Log .WithName ("config" )),
271
+ config .WithVersion (v ),
272
+ config .WithCollectorImage (collectorImage ),
273
+ config .WithCreateRBACPermissions (createRBACPermissions ),
274
+ config .WithEnableMultiInstrumentation (enableMultiInstrumentation ),
275
+ config .WithEnableApacheHttpdInstrumentation (enableApacheHttpdInstrumentation ),
276
+ config .WithEnableDotNetInstrumentation (enableDotNetInstrumentation ),
277
+ config .WithEnableNginxInstrumentation (enableNginxInstrumentation ),
278
+ config .WithEnablePythonInstrumentation (enablePythonInstrumentation ),
279
+ config .WithTargetAllocatorImage (targetAllocatorImage ),
280
+ config .WithOperatorOpAMPBridgeImage (operatorOpAMPBridgeImage ),
281
+ config .WithAutoInstrumentationJavaImage (autoInstrumentationJava ),
282
+ config .WithAutoInstrumentationNodeJSImage (autoInstrumentationNodeJS ),
283
+ config .WithAutoInstrumentationPythonImage (autoInstrumentationPython ),
284
+ config .WithAutoInstrumentationDotNetImage (autoInstrumentationDotNet ),
285
+ config .WithAutoInstrumentationGoImage (autoInstrumentationGo ),
286
+ config .WithAutoInstrumentationApacheHttpdImage (autoInstrumentationApacheHttpd ),
287
+ config .WithAutoInstrumentationNginxImage (autoInstrumentationNginx ),
288
+ config .WithAutoDetect (ad ),
289
+ config .WithLabelFilters (labelsFilter ),
290
+ config .WithAnnotationFilters (annotationsFilter ),
291
+ )
292
+ err = cfg .AutoDetect ()
294
293
if err != nil {
295
- setupLog .Error (clientErr , "failed to create kubernetes clientset" )
294
+ setupLog .Error (err , "failed to autodetect config variables" )
295
+ }
296
+ // Only add these to the scheme if they are available
297
+ if cfg .PrometheusCRAvailability () == prometheus .Available {
298
+ setupLog .Info ("Prometheus CRDs are installed, adding to scheme." )
299
+ utilruntime .Must (monitoringv1 .AddToScheme (scheme ))
300
+ } else {
301
+ setupLog .Info ("Prometheus CRDs are not installed, skipping adding to scheme." )
302
+ }
303
+ if cfg .OpenShiftRoutesAvailability () == openshift .RoutesAvailable {
304
+ setupLog .Info ("Openshift CRDs are installed, adding to scheme." )
305
+ utilruntime .Must (routev1 .Install (scheme ))
306
+ } else {
307
+ setupLog .Info ("Openshift CRDs are not installed, skipping adding to scheme." )
308
+ }
309
+
310
+ err = addDependencies (ctx , mgr , cfg , v )
311
+ if err != nil {
312
+ setupLog .Error (err , "failed to add/run bootstrap dependencies to the controller manager" )
313
+ os .Exit (1 )
296
314
}
297
- reviewer := rbac .NewReviewer (clientset )
298
315
299
316
if err = controllers .NewReconciler (controllers.Params {
300
317
Client : mgr .GetClient (),
@@ -410,3 +427,32 @@ func tlsConfigSetting(cfg *tls.Config, tlsOpt tlsConfig) {
410
427
}
411
428
cfg .CipherSuites = cipherSuiteIDs
412
429
}
430
+
431
+ func checkRbacPermissions (reviewer * rbac.Reviewer , ctx context.Context ) (admission.Warnings , error ) {
432
+ notPossibleToCheck := "unable to check rbac rules:"
433
+
434
+ namespace , err := autodetect .GetOperatorNamespace ()
435
+ if err != nil {
436
+ return nil , fmt .Errorf ("%s: %w" , notPossibleToCheck , err )
437
+ }
438
+
439
+ serviceAccount , err := autodetect .GetOperatorServiceAccount ()
440
+ if err != nil {
441
+ return nil , fmt .Errorf ("%s: %w" , notPossibleToCheck , err )
442
+ }
443
+
444
+ rules := []* rbacv1.PolicyRule {
445
+ {
446
+ APIGroups : []string {"rbac.authorization.k8s.io" },
447
+ Resources : []string {"clusterrolebindings" , "clusterroles" },
448
+ Verbs : []string {"create" , "delete" , "get" , "list" , "patch" , "update" },
449
+ },
450
+ }
451
+
452
+ if subjectAccessReviews , err := reviewer .CheckPolicyRules (ctx , serviceAccount , namespace , rules ... ); err != nil {
453
+ return nil , fmt .Errorf ("%s: %w" , notPossibleToCheck , err )
454
+ } else if allowed , deniedReviews := rbac .AllSubjectAccessReviewsAllowed (subjectAccessReviews ); ! allowed {
455
+ return rbac .WarningsGroupedByResource (deniedReviews ), nil
456
+ }
457
+ return nil , nil
458
+ }
0 commit comments