NormalizeNode takes a *yaml.Node and convert tag-style names into map-style, and converts other scalars into a canonical format
(n *yaml.Node)
| 45 | // NormalizeNode takes a *yaml.Node and convert tag-style names into map-style, |
| 46 | // and converts other scalars into a canonical format |
| 47 | func NormalizeNode(n *yaml.Node) error { |
| 48 | // Fix badly-parsed numbers |
| 49 | if n.ShortTag() == "!!float" && n.Value[0] == '0' { |
| 50 | n.Tag = "!!str" |
| 51 | } |
| 52 | |
| 53 | // Fix badly-parsed timestamps which are often used for versions in cloudformation |
| 54 | if n.ShortTag() == "!!timestamp" { |
| 55 | n.Tag = "!!str" |
| 56 | } |
| 57 | |
| 58 | // Convert tag-style intrinsics into map-style |
| 59 | for tag, funcName := range cft.Tags { |
| 60 | if n.ShortTag() == tag { |
| 61 | body := node.Clone(n) |
| 62 | |
| 63 | // Fix empty Fn values (should never be null) |
| 64 | if body.Tag == "!!null" { |
| 65 | body.Tag = "!!str" |
| 66 | } else { |
| 67 | body.Tag = "" |
| 68 | } |
| 69 | |
| 70 | // Wrap in a map |
| 71 | *n = yaml.Node{ |
| 72 | Kind: yaml.MappingNode, |
| 73 | Tag: "!!map", |
| 74 | Content: []*yaml.Node{ |
| 75 | { |
| 76 | Kind: yaml.ScalarNode, |
| 77 | Style: 0, |
| 78 | Tag: "!!str", |
| 79 | Value: funcName, |
| 80 | }, |
| 81 | body, |
| 82 | }, |
| 83 | } |
| 84 | |
| 85 | break |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | // Convert GetAtts |
| 90 | if n.Kind == yaml.MappingNode && len(n.Content) == 2 { |
| 91 | if n.Content[0].Value == "Fn::GetAtt" && n.Content[1].Kind == yaml.ScalarNode { |
| 92 | err := parseGetAtt(n.Content[1]) |
| 93 | if err != nil { |
| 94 | return err |
| 95 | } |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | for _, child := range n.Content { |
| 100 | err := NormalizeNode(child) |
| 101 | if err != nil { |
| 102 | return err |
| 103 | } |
| 104 | } |