Skip to content

Commit 96335d4

Browse files
fix: prevent nil pointer dereference in GetTemplateFromRef with podMetadata. Fixes #14968 (cherry-pick #14970 for 3.7) (#15029)
Signed-off-by: Bjoern Weidlich <[email protected]> Signed-off-by: Alan Clucas <[email protected]> Co-authored-by: Bjoern Weidlich <[email protected]>
1 parent 76b50ff commit 96335d4

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

workflow/templateresolution/context.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,13 @@ func (ctx *Context) GetTemplateFromRef(tmplRef *wfv1.TemplateRef) (*wfv1.Templat
155155

156156
template = wftmpl.GetTemplateByName(tmplRef.Template)
157157

158-
podMetadata := wftmpl.GetPodMetadata()
159-
ctx.addPodMetadata(podMetadata, template)
160-
161158
if template == nil {
162159
return nil, errors.Errorf(errors.CodeNotFound, "template %s not found in workflow template %s", tmplRef.Template, tmplRef.Name)
163160
}
161+
162+
podMetadata := wftmpl.GetPodMetadata()
163+
ctx.addPodMetadata(podMetadata, template)
164+
164165
return template.DeepCopy(), nil
165166
}
166167

workflow/templateresolution/context_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,53 @@ func TestOnWorkflowTemplate(t *testing.T) {
346346
tmpl := newCtx.tmplBase.GetTemplateByName("whalesay")
347347
assert.NotNil(t, tmpl)
348348
}
349+
350+
// TestGetTemplateFromRefWithPodMetadataAndMissingTemplate tests the bug where
351+
// GetTemplateFromRef causes a nil pointer dereference when:
352+
// 1. A WorkflowTemplate has podMetadata defined
353+
// 2. A templateRef references a template name that doesn't exist in that WorkflowTemplate
354+
func TestGetTemplateFromRefWithPodMetadataAndMissingTemplate(t *testing.T) {
355+
wfClientset := fakewfclientset.NewSimpleClientset()
356+
357+
// Create a WorkflowTemplate with podMetadata but without the template "nonexistent"
358+
workflowTemplateWithPodMetadata := `
359+
apiVersion: argoproj.io/v1alpha1
360+
kind: WorkflowTemplate
361+
metadata:
362+
name: template-with-podmetadata
363+
spec:
364+
podMetadata:
365+
labels:
366+
example-label: example-value
367+
annotations:
368+
example-annotation: example-value
369+
templates:
370+
- name: existing-template
371+
container:
372+
image: alpine:latest
373+
command: [echo, hello]
374+
`
375+
376+
err := createWorkflowTemplate(wfClientset, workflowTemplateWithPodMetadata)
377+
require.NoError(t, err)
378+
379+
// Create a base workflow template to use as context
380+
baseWftmpl := unmarshalWftmpl(baseWorkflowTemplateYaml)
381+
tplCtx := NewContextFromClientSet(
382+
wfClientset.ArgoprojV1alpha1().WorkflowTemplates(metav1.NamespaceDefault),
383+
wfClientset.ArgoprojV1alpha1().ClusterWorkflowTemplates(),
384+
baseWftmpl,
385+
nil,
386+
)
387+
388+
// Try to get a template that doesn't exist from a WorkflowTemplate that HAS podMetadata
389+
tmplRef := wfv1.TemplateRef{
390+
Name: "template-with-podmetadata",
391+
Template: "nonexistent-template",
392+
}
393+
394+
_, err = tplCtx.GetTemplateFromRef(&tmplRef)
395+
396+
require.Error(t, err)
397+
require.Contains(t, err.Error(), "template nonexistent-template not found in workflow template template-with-podmetadata")
398+
}

0 commit comments

Comments
 (0)