Skip to content

Commit 30a6d5e

Browse files
feat: Include node.name as a field for interpolation (argoproj#9641)
Signed-off-by: Ryan Copley <[email protected]> Signed-off-by: Ryan Copley <[email protected]> Co-authored-by: Saravanan Balasubramanian <[email protected]>
1 parent 1c99652 commit 30a6d5e

File tree

5 files changed

+90
-0
lines changed

5 files changed

+90
-0
lines changed

docs/variables.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ returns `0`. Please review the Sprig documentation to understand which functions
130130
| `inputs.parameters.<NAME>`| Input parameter to a template |
131131
| `inputs.parameters`| All input parameters to a template as a JSON string |
132132
| `inputs.artifacts.<NAME>` | Input artifact to a template |
133+
| `node.name` | Full name of the node |
133134

134135
### Steps Templates
135136

workflow/controller/operator.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,9 @@ func (woc *wfOperationCtx) executeTemplate(ctx context.Context, nodeName string,
17351735
if orgTmpl.IsWorkflowStep() {
17361736
localParams["steps.name"] = orgTmpl.GetName()
17371737
}
1738+
1739+
localParams["node.name"] = nodeName
1740+
17381741
// Merge Template defaults to template
17391742
err = woc.mergedTemplateDefaultsInto(resolvedTmpl)
17401743
if err != nil {

workflow/controller/operator_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6608,6 +6608,58 @@ func TestWorkflowScheduledTimeVariable(t *testing.T) {
66086608
assert.Equal(t, "2006-01-02T15:04:05-07:00", woc.globalParams[common.GlobalVarWorkflowCronScheduleTime])
66096609
}
66106610

6611+
var wfNodeNameField = `
6612+
apiVersion: argoproj.io/v1alpha1
6613+
kind: Workflow
6614+
metadata:
6615+
name: hello-world
6616+
spec:
6617+
entrypoint: main
6618+
templates:
6619+
- name: main
6620+
dag:
6621+
tasks:
6622+
- name: this-is-part-1
6623+
template: main2
6624+
- name: main2
6625+
steps:
6626+
- - name: this-is-part-2
6627+
template: whalesay
6628+
arguments:
6629+
parameters:
6630+
- name: message
6631+
value: "{{node.name}}"
6632+
- name: whalesay
6633+
inputs:
6634+
parameters:
6635+
- name: message
6636+
container:
6637+
image: docker/whalesay:latest
6638+
command: [cowsay]
6639+
args: ["{{ inputs.parameters.message }}"]
6640+
`
6641+
6642+
func TestWorkflowInterpolatesNodeNameField(t *testing.T) {
6643+
wf := wfv1.MustUnmarshalWorkflow(wfNodeNameField)
6644+
cancel, controller := newController(wf)
6645+
defer cancel()
6646+
6647+
ctx := context.Background()
6648+
woc := newWorkflowOperationCtx(wf, controller)
6649+
woc.operate(ctx)
6650+
6651+
foundPod := false
6652+
for _, element := range woc.wf.Status.Nodes {
6653+
if element.Type == "Pod" {
6654+
foundPod = true
6655+
assert.Equal(t, "hello-world.this-is-part-1", element.Inputs.Parameters[0].Value.String())
6656+
}
6657+
}
6658+
6659+
assert.True(t, foundPod)
6660+
6661+
}
6662+
66116663
func TestWorkflowShutdownStrategy(t *testing.T) {
66126664
wf := wfv1.MustUnmarshalWorkflow(`
66136665
apiVersion: argoproj.io/v1alpha1

workflow/validate/validate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ func resolveAllVariables(scope map[string]interface{}, globalParams map[string]s
610610
} else if strings.HasPrefix(tag, common.GlobalVarWorkflowDuration) {
611611
} else if strings.HasPrefix(tag, "tasks.name") {
612612
} else if strings.HasPrefix(tag, "steps.name") {
613+
} else if strings.HasPrefix(tag, "node.name") {
613614
} else if strings.HasPrefix(tag, "workflow.parameters") && workflowTemplateValidation {
614615
// If we are simply validating a WorkflowTemplate in isolation, some of the parameters may come from the Workflow that uses it
615616
} else {

workflow/validate/validate_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3018,6 +3018,39 @@ func TestInitContainerHasName(t *testing.T) {
30183018
assert.EqualError(t, err, "templates.main.tasks.spurious initContainers must all have container name")
30193019
}
30203020

3021+
var nodeNamePlumbsCorrectly = `
3022+
apiVersion: argoproj.io/v1alpha1
3023+
kind: Workflow
3024+
metadata:
3025+
generateName: hello-world-
3026+
spec:
3027+
entrypoint: main
3028+
templates:
3029+
- name: main
3030+
dag:
3031+
tasks:
3032+
- name: this-is-part-1
3033+
template: main2
3034+
- name: main2
3035+
steps:
3036+
- - name: this-is-part-2
3037+
template: main3
3038+
- name: main3
3039+
dag:
3040+
tasks:
3041+
- name: this-is-part-3
3042+
template: whalesay
3043+
- name: whalesay
3044+
container:
3045+
image: docker/whalesay:latest
3046+
command: [cowsay]
3047+
args: ["{{ node.name }}"]`
3048+
3049+
func TestNodeNameParameterInterpoliates(t *testing.T) {
3050+
err := validate(nodeNamePlumbsCorrectly)
3051+
assert.NoError(t, err)
3052+
}
3053+
30213054
func TestSubstituteGlobalVariablesLabelsAnnotations(t *testing.T) {
30223055
tests := []struct {
30233056
name string

0 commit comments

Comments
 (0)