@@ -113,6 +113,7 @@ type AgentRuntimeReconciler struct {
113113 EnableCardDiscovery bool
114114 SpireTrustDomain string
115115 GetFeatureGates func () * webhookconfig.FeatureGates
116+ GetPlatformConfig func () * webhookconfig.PlatformConfig
116117}
117118
118119func (r * AgentRuntimeReconciler ) getFeatureGates () * webhookconfig.FeatureGates {
@@ -122,6 +123,15 @@ func (r *AgentRuntimeReconciler) getFeatureGates() *webhookconfig.FeatureGates {
122123 return webhookconfig .DefaultFeatureGates ()
123124}
124125
126+ func (r * AgentRuntimeReconciler ) getPlatformConfig () * webhookconfig.PlatformConfig {
127+ if r .GetPlatformConfig != nil {
128+ if cfg := r .GetPlatformConfig (); cfg != nil {
129+ return cfg
130+ }
131+ }
132+ return webhookconfig .CompiledDefaults ()
133+ }
134+
125135// +kubebuilder:rbac:groups=agent.kagenti.dev,resources=agentruntimes,verbs=get;list;watch;create;update;patch;delete
126136// +kubebuilder:rbac:groups=agent.kagenti.dev,resources=agentruntimes/status,verbs=get;update;patch
127137// +kubebuilder:rbac:groups=agent.kagenti.dev,resources=agentruntimes/finalizers,verbs=update
@@ -194,6 +204,19 @@ func (r *AgentRuntimeReconciler) Reconcile(ctx context.Context, req ctrl.Request
194204 }
195205 }
196206
207+ // 4.5b. Ensure spiffe-helper-config CM is derived from PlatformConfig.
208+ // Unlike template CMs above, this always overwrites to keep PlatformConfig
209+ // as the single source of truth.
210+ if err := r .ensureSpiffeHelperConfigMap (ctx , rt .Namespace ); err != nil {
211+ logger .Error (err , "Failed to ensure spiffe-helper-config" )
212+ if r .Recorder != nil {
213+ r .Recorder .Eventf (rt , nil , corev1 .EventTypeWarning , "ConfigMapEnsureError" ,
214+ "EnsureSpiffeHelperConfig" , err .Error ())
215+ }
216+ r .updateErrorStatus (ctx , req .NamespacedName , ConditionTypeReady , "SpiffeHelperConfigError" , err .Error ())
217+ return ctrl.Result {RequeueAfter : 30 * time .Second }, nil
218+ }
219+
197220 // 4.6. Ensure namespace has Istio ambient mesh labels for ztunnel mTLS.
198221 istioLabeled , istioErr := r .ensureIstioMeshLabels (ctx , rt .Namespace )
199222 switch {
@@ -235,7 +258,7 @@ func (r *AgentRuntimeReconciler) Reconcile(ctx context.Context, req ctrl.Request
235258 }
236259
237260 // 5. Compute config hash from merged configuration (cluster → namespace)
238- configResult , err := ComputeConfigHash (ctx , r .Client , rt .Namespace )
261+ configResult , err := ComputeConfigHash (ctx , r .uncachedReader () , rt .Namespace )
239262 if err != nil {
240263 logger .Error (err , "Failed to compute config hash" )
241264 r .updateErrorStatus (ctx , req .NamespacedName , ConditionTypeReady , "ConfigHashError" , err .Error ())
@@ -1045,7 +1068,6 @@ func computeCardContentHash(cardData *agentv1alpha1.AgentCardData) string {
10451068var templateConfigMapNames = []string {
10461069 "authbridge-config" ,
10471070 "authbridge-runtime-config" ,
1048- "spiffe-helper-config" ,
10491071}
10501072
10511073// ensureNamespaceConfigMaps copies template ConfigMaps from kagenti-system to the
@@ -1097,6 +1119,65 @@ func (r *AgentRuntimeReconciler) ensureNamespaceConfigMaps(ctx context.Context,
10971119 return nil
10981120}
10991121
1122+ // ensureSpiffeHelperConfigMap creates or updates the spiffe-helper-config ConfigMap
1123+ // in the target namespace using content from PlatformConfig. Unlike template CMs
1124+ // which are create-if-not-exists, this always overwrites because PlatformConfig is
1125+ // the single source of truth.
1126+ func (r * AgentRuntimeReconciler ) ensureSpiffeHelperConfigMap (ctx context.Context , namespace string ) error {
1127+ logger := log .FromContext (ctx )
1128+ cfg := r .getPlatformConfig ()
1129+
1130+ desired := & corev1.ConfigMap {
1131+ ObjectMeta : metav1.ObjectMeta {
1132+ Name : SpiffeHelperConfigMapName ,
1133+ Namespace : namespace ,
1134+ Labels : map [string ]string {
1135+ LabelManagedBy : LabelManagedByValue ,
1136+ },
1137+ },
1138+ Data : map [string ]string {
1139+ "helper.conf" : cfg .Spiffe .HelperConfig ,
1140+ },
1141+ }
1142+
1143+ existing := & corev1.ConfigMap {}
1144+ err := r .uncachedReader ().Get (ctx , client.ObjectKey {Namespace : namespace , Name : SpiffeHelperConfigMapName }, existing )
1145+ if apierrors .IsNotFound (err ) {
1146+ if err := r .Create (ctx , desired ); err != nil {
1147+ if apierrors .IsAlreadyExists (err ) {
1148+ return nil
1149+ }
1150+ return fmt .Errorf ("failed to create spiffe-helper-config in %s: %w" , namespace , err )
1151+ }
1152+ logger .Info ("Created spiffe-helper-config from PlatformConfig" , "namespace" , namespace )
1153+ return nil
1154+ }
1155+ if err != nil {
1156+ return fmt .Errorf ("failed to check spiffe-helper-config in %s: %w" , namespace , err )
1157+ }
1158+
1159+ needsUpdate := existing .Data ["helper.conf" ] != cfg .Spiffe .HelperConfig
1160+
1161+ if existing .Labels == nil {
1162+ existing .Labels = make (map [string ]string )
1163+ }
1164+ if existing .Labels [LabelManagedBy ] != LabelManagedByValue {
1165+ existing .Labels [LabelManagedBy ] = LabelManagedByValue
1166+ needsUpdate = true
1167+ }
1168+
1169+ if ! needsUpdate {
1170+ return nil
1171+ }
1172+
1173+ existing .Data = desired .Data
1174+ if err := r .Update (ctx , existing ); err != nil {
1175+ return fmt .Errorf ("failed to update spiffe-helper-config in %s: %w" , namespace , err )
1176+ }
1177+ logger .Info ("Updated spiffe-helper-config from PlatformConfig" , "namespace" , namespace )
1178+ return nil
1179+ }
1180+
11001181const (
11011182 sccClusterRoleName = "system:openshift:scc:kagenti-authbridge"
11021183 sccRoleBindingName = "agent-authbridge-scc"
0 commit comments