Skip to content

Commit 14d8bfe

Browse files
authored
feat: handle timestamps as strings in YAML parsing (#669)
Signed-off-by: yxxhero <aiopsclub@163.com>
1 parent aa097c8 commit 14d8bfe

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

io.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,32 @@ func nodesFromReader(reader io.Reader) ([]yaml.Node, error) {
7070
break
7171
}
7272
if len(node.Content[0].Content) > 0 {
73+
replaceTimestamp(&node)
7374
nodes = append(nodes, node)
7475
}
7576
}
7677
return nodes, nil
7778
}
7879

80+
// A custom unmarshal is needed because go-yaml parse "YYYY-MM-DD" as a full
81+
// timestamp, writing YYYY-MM-DD HH:MM:SS +0000 UTC when encoding, so we are
82+
// going to treat timestamps as strings.
83+
// See: https://github.com/go-yaml/yaml/issues/770
84+
85+
func replaceTimestamp(n *yaml.Node) {
86+
if len(n.Content) == 0 {
87+
return
88+
}
89+
for _, innerNode := range n.Content {
90+
if innerNode.Tag == "!!map" {
91+
replaceTimestamp(innerNode)
92+
}
93+
if innerNode.Tag == "!!timestamp" {
94+
innerNode.Tag = "!!str"
95+
}
96+
}
97+
}
98+
7999
func Output(output io.Writer, format string, nodes []yaml.Node) error {
80100
for i, node := range nodes {
81101
var v interface{}

vals_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,37 @@ func TestEvalNodesWithDictionaries(t *testing.T) {
149149

150150
require.Equal(t, expected, buf.String())
151151
}
152+
153+
func TestEvalNodesWithTime(t *testing.T) {
154+
var yamlDocs = `
155+
date: 2025-01-01
156+
datetime: 2025-01-01T12:34:56Z
157+
datetime_millis: 2025-01-01T12:34:56.789Z
158+
datetime_offset: 2025-01-01T12:34:56+01:00
159+
`
160+
161+
var expected = `date: "2025-01-01"
162+
datetime: "2025-01-01T12:34:56Z"
163+
datetime_millis: "2025-01-01T12:34:56.789Z"
164+
datetime_offset: "2025-01-01T12:34:56+01:00"
165+
`
166+
167+
tmpFile, err := os.CreateTemp("", "secrets.yaml")
168+
defer os.Remove(tmpFile.Name())
169+
require.NoError(t, err)
170+
171+
_, err = tmpFile.WriteString(yamlDocs)
172+
require.NoError(t, err)
173+
174+
input, err := Inputs(tmpFile.Name())
175+
require.NoError(t, err)
176+
177+
nodes, err := EvalNodes(input, Options{})
178+
require.NoError(t, err)
179+
buf := new(strings.Builder)
180+
181+
err = Output(buf, "", nodes)
182+
require.NoError(t, err)
183+
184+
require.Equal(t, expected, buf.String())
185+
}

0 commit comments

Comments
 (0)