@@ -71,13 +71,21 @@ var defaultRBACRules = []rbacv1.PolicyRule{
71
71
Resources : []string {"pods/attach" },
72
72
Verbs : []string {"create" , "get" },
73
73
},
74
+ {
75
+ APIGroups : []string {"" },
76
+ Resources : []string {"configmaps" },
77
+ Verbs : []string {"get" , "list" , "watch" },
78
+ },
74
79
}
75
80
76
81
var ctxLogger = log .FromContext (context .Background ())
77
82
78
83
// mcpContainerName is the name of the mcp container used in pod templates
79
84
const mcpContainerName = "mcp"
80
85
86
+ // trueValue is the string value "true" used for environment variable comparisons
87
+ const trueValue = "true"
88
+
81
89
// Authorization ConfigMap label constants
82
90
const (
83
91
// authzLabelKey is the label key for authorization configuration type
@@ -463,38 +471,51 @@ func (r *MCPServerReconciler) deploymentForMCPServer(ctx context.Context, m *mcp
463
471
464
472
// Prepare container args
465
473
args := []string {"run" , "--foreground=true" }
466
- args = append (args , fmt .Sprintf ("--proxy-port=%d" , m .Spec .Port ))
467
- args = append (args , fmt .Sprintf ("--name=%s" , m .Name ))
468
- args = append (args , fmt .Sprintf ("--transport=%s" , m .Spec .Transport ))
469
- args = append (args , fmt .Sprintf ("--host=%s" , getProxyHost ()))
470
474
471
- if m .Spec .TargetPort != 0 {
472
- args = append (args , fmt .Sprintf ("--target-port=%d" , m .Spec .TargetPort ))
473
- }
474
-
475
- // Generate pod template patch for secrets and merge with user-provided patch
476
-
477
- finalPodTemplateSpec := NewMCPServerPodTemplateSpecBuilder (m .Spec .PodTemplateSpec ).
478
- WithServiceAccount (m .Spec .ServiceAccount ).
479
- WithSecrets (m .Spec .Secrets ).
480
- Build ()
481
- // Add pod template patch if we have one
482
- if finalPodTemplateSpec != nil {
483
- podTemplatePatch , err := json .Marshal (finalPodTemplateSpec )
484
- if err != nil {
485
- logger .Errorf ("Failed to marshal pod template spec: %v" , err )
486
- } else {
487
- args = append (args , fmt .Sprintf ("--k8s-pod-patch=%s" , string (podTemplatePatch )))
475
+ // Check if global ConfigMap mode is enabled via environment variable
476
+ useConfigMap := os .Getenv ("TOOLHIVE_USE_CONFIGMAP" ) == trueValue
477
+ if useConfigMap {
478
+ // Use the operator-created ConfigMap (format: {name}-runconfig)
479
+ configMapName := fmt .Sprintf ("%s-runconfig" , m .Name )
480
+ configMapRef := fmt .Sprintf ("%s/%s" , m .Namespace , configMapName )
481
+ args = append (args , fmt .Sprintf ("--from-configmap=%s" , configMapRef ))
482
+ } else {
483
+ // Use individual configuration flags (existing behavior)
484
+ args = append (args , fmt .Sprintf ("--proxy-port=%d" , m .Spec .Port ))
485
+ args = append (args , fmt .Sprintf ("--name=%s" , m .Name ))
486
+ args = append (args , fmt .Sprintf ("--transport=%s" , m .Spec .Transport ))
487
+ args = append (args , fmt .Sprintf ("--host=%s" , getProxyHost ()))
488
+ if m .Spec .TargetPort != 0 {
489
+ args = append (args , fmt .Sprintf ("--target-port=%d" , m .Spec .TargetPort ))
490
+ }
491
+ }
492
+
493
+ // Add pod template patch and permission profile only if not using ConfigMap
494
+ // When using ConfigMap, these are included in the runconfig.json
495
+ if ! useConfigMap {
496
+ // Generate pod template patch for secrets and merge with user-provided patch
497
+ finalPodTemplateSpec := NewMCPServerPodTemplateSpecBuilder (m .Spec .PodTemplateSpec ).
498
+ WithServiceAccount (m .Spec .ServiceAccount ).
499
+ WithSecrets (m .Spec .Secrets ).
500
+ Build ()
501
+ // Add pod template patch if we have one
502
+ if finalPodTemplateSpec != nil {
503
+ podTemplatePatch , err := json .Marshal (finalPodTemplateSpec )
504
+ if err != nil {
505
+ logger .Errorf ("Failed to marshal pod template spec: %v" , err )
506
+ } else {
507
+ args = append (args , fmt .Sprintf ("--k8s-pod-patch=%s" , string (podTemplatePatch )))
508
+ }
488
509
}
489
- }
490
510
491
- // Add permission profile args
492
- if m .Spec .PermissionProfile != nil {
493
- switch m .Spec .PermissionProfile .Type {
494
- case mcpv1alpha1 .PermissionProfileTypeBuiltin :
495
- args = append (args , fmt .Sprintf ("--permission-profile=%s" , m .Spec .PermissionProfile .Name ))
496
- case mcpv1alpha1 .PermissionProfileTypeConfigMap :
497
- args = append (args , fmt .Sprintf ("--permission-profile-path=/etc/toolhive/profiles/%s" , m .Spec .PermissionProfile .Key ))
511
+ // Add permission profile args
512
+ if m .Spec .PermissionProfile != nil {
513
+ switch m .Spec .PermissionProfile .Type {
514
+ case mcpv1alpha1 .PermissionProfileTypeBuiltin :
515
+ args = append (args , fmt .Sprintf ("--permission-profile=%s" , m .Spec .PermissionProfile .Name ))
516
+ case mcpv1alpha1 .PermissionProfileTypeConfigMap :
517
+ args = append (args , fmt .Sprintf ("--permission-profile-path=/etc/toolhive/profiles/%s" , m .Spec .PermissionProfile .Key ))
518
+ }
498
519
}
499
520
}
500
521
@@ -526,15 +547,18 @@ func (r *MCPServerReconciler) deploymentForMCPServer(ctx context.Context, m *mcp
526
547
args = append (args , "--enable-audit" )
527
548
}
528
549
529
- // Add environment variables as --env flags for the MCP server
530
- for _ , e := range m .Spec .Env {
531
- args = append (args , fmt .Sprintf ("--env=%s=%s" , e .Name , e .Value ))
532
- }
550
+ // Add environment variables and tools filter only if not using ConfigMap
551
+ if ! useConfigMap {
552
+ // Add environment variables as --env flags for the MCP server
553
+ for _ , e := range m .Spec .Env {
554
+ args = append (args , fmt .Sprintf ("--env=%s=%s" , e .Name , e .Value ))
555
+ }
533
556
534
- // Add tools filter args
535
- if len (m .Spec .ToolsFilter ) > 0 {
536
- slices .Sort (m .Spec .ToolsFilter )
537
- args = append (args , fmt .Sprintf ("--tools=%s" , strings .Join (m .Spec .ToolsFilter , "," )))
557
+ // Add tools filter args
558
+ if len (m .Spec .ToolsFilter ) > 0 {
559
+ slices .Sort (m .Spec .ToolsFilter )
560
+ args = append (args , fmt .Sprintf ("--tools=%s" , strings .Join (m .Spec .ToolsFilter , "," )))
561
+ }
538
562
}
539
563
540
564
// Add OpenTelemetry configuration args
@@ -550,11 +574,13 @@ func (r *MCPServerReconciler) deploymentForMCPServer(ctx context.Context, m *mcp
550
574
}
551
575
}
552
576
553
- // Add the image
577
+ // Always add the image as it's required by proxy runner command signature
578
+ // When using ConfigMap, the image from ConfigMap takes precedence, but we still need
579
+ // to provide this as a positional argument to satisfy the command requirements
554
580
args = append (args , m .Spec .Image )
555
581
556
- // Add additional args
557
- if len (m .Spec .Args ) > 0 {
582
+ // Add additional args only if not using ConfigMap
583
+ if ! useConfigMap && len (m .Spec .Args ) > 0 {
558
584
args = append (args , "--" )
559
585
args = append (args , m .Spec .Args ... )
560
586
}
0 commit comments