Skip to content

Commit d17e668

Browse files
accessor for step error in templating values (#16)
Signed-off-by: Pablo Pérez Schröder <[email protected]>
1 parent 8996ecc commit d17e668

File tree

7 files changed

+39
-5
lines changed

7 files changed

+39
-5
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ A user can be allowed to resolve a task in three ways:
142142
- `.resolver_input.[INPUT_NAME]`: the value of an input provided by the task's resolver
143143
- `.step.[STEP_NAME].output.foo`: field `foo` from the output of a named step
144144
- `.step.[STEP_NAME].metadata.HTTPStatus`: field `HTTPStatus` from the metadata of a named step
145+
- `.step.[STEP_NAME].children`: the collection of results from a 'foreach' step
146+
- `.step.[STEP_NAME].error`: error message from a failed step
145147
- `.config.[CONFIG_ITEM].bar`: field `bar` from a config item (configstore, see above)
146148
- `.iterator.foo`: field `foo` from the iterator in a loop (see `foreach` steps below)
147149

engine/engine.go

+1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ func resolve(dbp zesty.DBProvider, res *resolution.Resolution, t *task.Task, deb
348348
res.Values.SetOutput(s.Name, s.Output)
349349
res.Values.SetMetadata(s.Name, s.Metadata)
350350
res.Values.SetChildren(s.Name, s.Children)
351+
res.Values.SetError(s.Name, s.Error)
351352

352353
// call after-run step logic
353354
modifiedSteps := map[string]bool{

engine/engine_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,12 @@ func TestSimpleTemplate(t *testing.T) {
162162
res, err := runTask("simple.yaml", input, nil)
163163

164164
assert.Equal(t, nil, err)
165-
assert.Equal(t, resolution.StateDone, res.State)
165+
assert.Equal(t, resolution.StateError, res.State)
166166
assert.Equal(t, step.StateDone, res.Steps["stepOne"].State)
167167
assert.Equal(t, step.StateDone, res.Steps["stepTwo"].State)
168+
assert.Equal(t, step.StateServerError, res.Steps["stepThree"].State)
169+
170+
assert.Equal(t, "FAIL!", res.Values.GetError("stepThree"))
168171
}
169172

170173
func TestClientError(t *testing.T) {

engine/step/condition.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const (
1818
LT = "LT"
1919
GE = "GE"
2020
LE = "LE"
21-
REGEXP = "regexp"
21+
REGEXP = "REGEXP"
2222
)
2323

2424
type (
@@ -51,7 +51,7 @@ func (a *Assert) Eval(v *values.Values, item interface{}, stepName string) error
5151
valStr := strings.Replace(string(val), "<no value>", "", -1)
5252
expStr := strings.Replace(string(expected), "<no value>", "", -1)
5353

54-
switch a.Operator {
54+
switch strings.ToUpper(a.Operator) { // normalized operator, accept both lower case and upper case from template
5555
case EQ:
5656
if valStr != expStr {
5757
return ErrConditionNotMet(fmt.Sprintf("Condition not met: expected '%s', got '%s': %s", expStr, valStr, a.Message))
@@ -100,7 +100,7 @@ func (a *Assert) Eval(v *values.Values, item interface{}, stepName string) error
100100
// ie. the operator is among the accepted values listed above
101101
func (a *Assert) Valid() error {
102102
if a != nil {
103-
switch a.Operator {
103+
switch strings.ToUpper(a.Operator) {
104104
case EQ, NE, GT, LT, GE, LE:
105105
case REGEXP:
106106
if _, err := regexp.Compile(a.Expected); err != nil {

engine/templates_tests/simple.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ steps:
1717
configuration:
1818
output:
1919
foo: baz
20+
stepThree:
21+
description: third step, fails
22+
dependencies: [stepTwo]
23+
action:
24+
type: echo
25+
configuration:
26+
error_message: FAIL!
27+

engine/values/values.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99

1010
"github.com/Masterminds/sprig"
1111
"github.com/juju/errors"
12-
"github.com/robertkrimen/otto"
1312
"github.com/ovh/utask"
13+
"github.com/robertkrimen/otto"
1414
)
1515

1616
// keys to store/retrieve data from a Values struct
@@ -26,6 +26,7 @@ const (
2626
OutputKey = "output"
2727
MetadataKey = "metadata"
2828
ChildrenKey = "children"
29+
ErrorKey = "error"
2930
)
3031

3132
// Values is a container for all the live data of a running task
@@ -124,6 +125,21 @@ func (v *Values) UnsetChildren(stepName string) {
124125
v.unsetStepData(stepName, ChildrenKey)
125126
}
126127

128+
// GetError returns the error resulting from a failed step
129+
func (v *Values) GetError(stepName string) interface{} {
130+
return v.getStepData(stepName, ErrorKey)
131+
}
132+
133+
// SetChildren stores the error resulting from a failed step
134+
func (v *Values) SetError(stepName string, value interface{}) {
135+
v.setStepData(stepName, ErrorKey, value)
136+
}
137+
138+
// UnsetChildren empties the error from a failed step
139+
func (v *Values) UnsetError(stepName string) {
140+
v.unsetStepData(stepName, ErrorKey)
141+
}
142+
127143
func (v *Values) getStepData(stepName, field string) interface{} {
128144
stepmap := v.m[StepKey].(map[string]interface{})
129145
if stepmap[stepName] == nil {
@@ -213,6 +229,9 @@ func (v *Values) Apply(templateStr string, item interface{}, stepName string) ([
213229

214230
v.SetChildren(utask.This, v.GetChildren(stepName))
215231
defer v.UnsetChildren(utask.This)
232+
233+
v.SetError(utask.This, v.GetError(stepName))
234+
defer v.UnsetError(utask.This)
216235
}
217236

218237
err = tmpl.Execute(b, v.m)

models/resolution/resolution.go

+1
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ func (r *Resolution) setSteps(st map[string]*step.Step) {
460460
r.Values.SetOutput(name, s.Output)
461461
r.Values.SetMetadata(name, s.Metadata)
462462
r.Values.SetChildren(name, s.Children)
463+
r.Values.SetError(s.Name, s.Error)
463464
}
464465
}
465466

0 commit comments

Comments
 (0)