Skip to content

Commit c9cba3b

Browse files
fix: prevent nil pointer dereference in GetTemplateFromRef with podMetadata. Fixes #14968 (#14970)
Signed-off-by: Bjoern Weidlich <[email protected]>
1 parent 801b82a commit c9cba3b

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

workflow/templateresolution/context.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,13 @@ func (tplCtx *TemplateContext) GetTemplateFromRef(ctx context.Context, tmplRef *
149149

150150
template = wftmpl.GetTemplateByName(tmplRef.Template)
151151

152-
podMetadata := wftmpl.GetPodMetadata()
153-
tplCtx.addPodMetadata(podMetadata, template)
154-
155152
if template == nil {
156153
return nil, errors.Errorf(errors.CodeNotFound, "template %s not found in workflow template %s", tmplRef.Template, tmplRef.Name)
157154
}
155+
156+
podMetadata := wftmpl.GetPodMetadata()
157+
tplCtx.addPodMetadata(podMetadata, template)
158+
158159
return template.DeepCopy(), nil
159160
}
160161

workflow/templateresolution/context_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,56 @@ func TestOnWorkflowTemplate(t *testing.T) {
362362
tmpl := newCtx.tmplBase.GetTemplateByName("whalesay")
363363
assert.NotNil(t, tmpl)
364364
}
365+
366+
// TestGetTemplateFromRefWithPodMetadataAndMissingTemplate tests the bug where
367+
// GetTemplateFromRef causes a nil pointer dereference when:
368+
// 1. A WorkflowTemplate has podMetadata defined
369+
// 2. A templateRef references a template name that doesn't exist in that WorkflowTemplate
370+
func TestGetTemplateFromRefWithPodMetadataAndMissingTemplate(t *testing.T) {
371+
ctx := logging.TestContext(t.Context())
372+
wfClientset := fakewfclientset.NewSimpleClientset()
373+
374+
// Create a WorkflowTemplate with podMetadata but without the template "nonexistent"
375+
workflowTemplateWithPodMetadata := `
376+
apiVersion: argoproj.io/v1alpha1
377+
kind: WorkflowTemplate
378+
metadata:
379+
name: template-with-podmetadata
380+
spec:
381+
podMetadata:
382+
labels:
383+
example-label: example-value
384+
annotations:
385+
example-annotation: example-value
386+
templates:
387+
- name: existing-template
388+
container:
389+
image: alpine:latest
390+
command: [echo, hello]
391+
`
392+
393+
err := createWorkflowTemplate(ctx, wfClientset, workflowTemplateWithPodMetadata)
394+
require.NoError(t, err)
395+
396+
// Create a base workflow template to use as context
397+
baseWftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml)
398+
log := logging.RequireLoggerFromContext(ctx)
399+
tplCtx := NewContextFromClientSet(
400+
wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault),
401+
wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(),
402+
baseWftmpl,
403+
nil,
404+
log,
405+
)
406+
407+
// Try to get a template that doesn't exist from a WorkflowTemplate that HAS podMetadata
408+
tmplRef := wfv1.TemplateRef{
409+
Name: "template-with-podmetadata",
410+
Template: "nonexistent-template",
411+
}
412+
413+
_, err = tplCtx.GetTemplateFromRef(ctx, &tmplRef)
414+
415+
require.Error(t, err)
416+
require.Contains(t, err.Error(), "template nonexistent-template not found in workflow template template-with-podmetadata")
417+
}

0 commit comments

Comments
 (0)