Skip to content

Commit 8db5f83

Browse files
committed
Enhance Git configuration handling in session management
- Extracted Git configuration details from the session spec, including user name, email, SSH key secret, and token secret, to improve clarity and maintainability. - Updated environment variable construction to include Git-related variables, ensuring they are correctly set for the session. - Added support for mounting runner secrets as a volume, enhancing security and access to sensitive information during job execution.
1 parent ab97572 commit 8db5f83

File tree

1 file changed

+64
-93
lines changed

1 file changed

+64
-93
lines changed

components/operator/main.go

Lines changed: 64 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,13 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
261261
maxTokens, _, _ := unstructured.NestedInt64(llmSettings, "maxTokens")
262262
workspaceStorePath, workspaceStorePathFound, _ := unstructured.NestedString(spec, "paths", "workspace")
263263
messageStorePath, messageStorePathFound, _ := unstructured.NestedString(spec, "paths", "messages")
264-
265-
// Git configuration is derived later directly from spec when building envs
264+
// Extract git configuration
265+
gitConfig, _, _ := unstructured.NestedMap(spec, "gitConfig")
266+
gitUserName, _, _ := unstructured.NestedString(gitConfig, "user", "name")
267+
gitUserEmail, _, _ := unstructured.NestedString(gitConfig, "user", "email")
268+
sshKeySecret, _, _ := unstructured.NestedString(gitConfig, "authentication", "sshKeySecret")
269+
tokenSecret, _, _ := unstructured.NestedString(gitConfig, "authentication", "tokenSecret")
270+
repositories, _, _ := unstructured.NestedSlice(gitConfig, "repositories")
266271

267272
// Read runner secrets configuration from ProjectSettings in the session's namespace
268273
runnerSecretsName := ""
@@ -327,10 +332,6 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
327332
},
328333
},
329334
RestartPolicy: corev1.RestartPolicyNever,
330-
331-
// ⚠️ Let OpenShift SCC choose UID/GID dynamically (restricted-v2 compatible)
332-
// SecurityContext omitted to allow SCC assignment
333-
334335
Volumes: []corev1.Volume{
335336
{
336337
Name: "workspace",
@@ -383,108 +384,61 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
383384
}
384385
return fmt.Sprintf("/sessions/%s/messages.json", name)
385386
}()},
386-
387-
// (Optional) proxy envs if your cluster requires them:
388-
// { Name: "HTTPS_PROXY", Value: "http://proxy.corp:3128" },
389-
// { Name: "NO_PROXY", Value: ".svc,.cluster.local,10.0.0.0/8" },
387+
{Name: "GIT_USER_NAME", Value: gitUserName},
388+
{Name: "GIT_USER_EMAIL", Value: gitUserEmail},
389+
{Name: "GIT_SSH_KEY_SECRET", Value: sshKeySecret},
390+
{Name: "GIT_TOKEN_SECRET", Value: tokenSecret},
391+
{Name: "GIT_REPOSITORIES", Value: fmt.Sprintf("%v", repositories)},
390392
}
391-
// Always attempt to map ANTHROPIC_API_KEY from the runner secret in this namespace.
392-
// Fallback to default name if ProjectSettings.spec.runnerSecretsName is not set.
393-
secretName := runnerSecretsName
394-
if secretName == "" {
395-
secretName = "ambient-code-secrets"
393+
// If backend annotated the session with a runner token secret, inject bot token envs without refetching the CR
394+
if meta, ok := currentObj.Object["metadata"].(map[string]interface{}); ok {
395+
if anns, ok := meta["annotations"].(map[string]interface{}); ok {
396+
if v, ok := anns["ambient-code.io/runner-token-secret"].(string); ok && strings.TrimSpace(v) != "" {
397+
secretName := strings.TrimSpace(v)
398+
base = append(base, corev1.EnvVar{Name: "AUTH_MODE", Value: "bot_token"})
399+
base = append(base, corev1.EnvVar{
400+
Name: "BOT_TOKEN",
401+
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{
402+
LocalObjectReference: corev1.LocalObjectReference{Name: secretName},
403+
Key: "token",
404+
}},
405+
})
406+
}
407+
}
396408
}
397-
base = append(base, corev1.EnvVar{
398-
Name: "ANTHROPIC_API_KEY",
399-
ValueFrom: &corev1.EnvVarSource{
400-
SecretKeyRef: &corev1.SecretKeySelector{
401-
LocalObjectReference: corev1.LocalObjectReference{Name: secretName},
402-
Key: "anthropic-api-key",
403-
},
404-
},
405-
})
406-
// If backend annotated the session with a runner token secret, inject bot token envs
407-
gvr := getAgenticSessionResource()
408-
if obj, err := dynamicClient.Resource(gvr).Namespace(sessionNamespace).Get(context.TODO(), name, v1.GetOptions{}); err == nil {
409-
if meta, ok := obj.Object["metadata"].(map[string]interface{}); ok {
410-
if anns, ok := meta["annotations"].(map[string]interface{}); ok {
411-
if v, ok := anns["ambient-code.io/runner-token-secret"].(string); ok && strings.TrimSpace(v) != "" {
412-
secretName := strings.TrimSpace(v)
413-
base = append(base, corev1.EnvVar{Name: "AUTH_MODE", Value: "bot_token"})
414-
base = append(base, corev1.EnvVar{
415-
Name: "BOT_TOKEN",
416-
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{
417-
LocalObjectReference: corev1.LocalObjectReference{Name: secretName},
418-
Key: "token",
419-
}},
420-
})
421-
}
422-
// Derive GITHUB_REPO from spec.gitConfig.repositories[0].url if present
423-
if spec, ok := obj.Object["spec"].(map[string]interface{}); ok {
424-
if gc, ok := spec["gitConfig"].(map[string]interface{}); ok {
425-
if repos, ok := gc["repositories"].([]interface{}); ok && len(repos) > 0 {
426-
if r0, ok := repos[0].(map[string]interface{}); ok {
427-
if url, ok := r0["url"].(string); ok && strings.TrimSpace(url) != "" {
428-
base = append(base, corev1.EnvVar{Name: "GITHUB_REPO", Value: url})
429-
}
430-
if user, ok := gc["user"].(map[string]interface{}); ok {
431-
if v, ok := user["name"].(string); ok {
432-
base = append(base, corev1.EnvVar{Name: "GIT_USER_NAME", Value: v})
433-
}
434-
if v, ok := user["email"].(string); ok {
435-
base = append(base, corev1.EnvVar{Name: "GIT_USER_EMAIL", Value: v})
436-
}
437-
}
438-
}
439-
}
440-
}
441-
}
442-
// Apply paths overrides from spec.paths
443-
if spec, ok := obj.Object["spec"].(map[string]interface{}); ok {
444-
if paths, ok := spec["paths"].(map[string]interface{}); ok {
445-
if v, ok := paths["workspace"].(string); ok && strings.TrimSpace(v) != "" {
446-
base = append(base, corev1.EnvVar{Name: "WORKSPACE_STORE_PATH", Value: v})
447-
}
448-
if v, ok := paths["messages"].(string); ok && strings.TrimSpace(v) != "" {
449-
base = append(base, corev1.EnvVar{Name: "MESSAGE_STORE_PATH", Value: v})
409+
// Add CR-provided envs last (override base when same key)
410+
if spec, ok := obj.Object["spec"].(map[string]interface{}); ok {
411+
if envMap, ok := spec["environmentVariables"].(map[string]interface{}); ok {
412+
for k, v := range envMap {
413+
if vs, ok := v.(string); ok {
414+
// replace if exists
415+
replaced := false
416+
for i := range base {
417+
if base[i].Name == k {
418+
base[i].Value = vs
419+
replaced = true
420+
break
450421
}
451422
}
452-
}
453-
// Apply environmentVariables from spec if provided (override defaults)
454-
if spec, ok := obj.Object["spec"].(map[string]interface{}); ok {
455-
if envMap, ok := spec["environmentVariables"].(map[string]interface{}); ok {
456-
// helper to set/replace env var
457-
setEnv := func(k, v string) {
458-
// replace if exists
459-
for i := range base {
460-
if base[i].Name == k {
461-
base[i].Value = v
462-
return
463-
}
464-
}
465-
base = append(base, corev1.EnvVar{Name: k, Value: v})
466-
}
467-
for k, v := range envMap {
468-
if vs, ok := v.(string); ok {
469-
setEnv(k, vs)
470-
}
471-
}
423+
if !replaced {
424+
base = append(base, corev1.EnvVar{Name: k, Value: vs})
472425
}
473426
}
474427
}
475428
}
476429
}
430+
477431
return base
478432
}(),
479433

480434
// If configured, import all keys from the runner Secret as environment variables
481435
EnvFrom: func() []corev1.EnvFromSource {
482-
if runnerSecretsName == "" {
483-
return nil
484-
}
485-
return []corev1.EnvFromSource{
486-
{SecretRef: &corev1.SecretEnvSource{LocalObjectReference: corev1.LocalObjectReference{Name: runnerSecretsName}}},
436+
if runnerSecretsName != "" {
437+
return []corev1.EnvFromSource{
438+
{SecretRef: &corev1.SecretEnvSource{LocalObjectReference: corev1.LocalObjectReference{Name: runnerSecretsName}}},
439+
}
487440
}
441+
return []corev1.EnvFromSource{}
488442
}(),
489443

490444
Resources: corev1.ResourceRequirements{},
@@ -495,6 +449,23 @@ func handleAgenticSessionEvent(obj *unstructured.Unstructured) error {
495449
},
496450
}
497451

452+
// If a runner secret is configured, mount it as a volume in addition to EnvFrom
453+
if runnerSecretsName != "" {
454+
job.Spec.Template.Spec.Volumes = append(job.Spec.Template.Spec.Volumes, corev1.Volume{
455+
Name: "runner-secrets",
456+
VolumeSource: corev1.VolumeSource{
457+
Secret: &corev1.SecretVolumeSource{SecretName: runnerSecretsName},
458+
},
459+
})
460+
if len(job.Spec.Template.Spec.Containers) > 0 {
461+
job.Spec.Template.Spec.Containers[0].VolumeMounts = append(job.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
462+
Name: "runner-secrets",
463+
MountPath: "/var/run/runner-secrets",
464+
ReadOnly: true,
465+
})
466+
}
467+
}
468+
498469
// Update status to Creating before attempting job creation
499470
if err := updateAgenticSessionStatus(sessionNamespace, name, map[string]interface{}{
500471
"phase": "Creating",

0 commit comments

Comments
 (0)