我的Yaml文件的一部分
rules:
- action:
count: {}
name: rulenumbertwo
priority: 123
statement:
bytematchstatement:
fieldtomatch:
singleheader:
name: foobar
positionalconstraint: CONTAINS
searchstring: [103, 105, 122, 122, 98, 117, 122, 122]
以上内容作为搜索字符串值的相应ASCII字符串("fizzbuzz"(出现。但是我怎样才能把它写成人类可读的格式呢?手册上说搜索字符串应该是";自动地";已转换,但如果我不将其写成ASCII代码数组,则会引发错误。
我的代码(试图对其进行解组,如果我直接编写数组,但它不是人类可读的,这是有效的(:
d := &wafv2.UpdateRuleGroupInput{}
err = yaml.Unmarshal(buf, d)
我想把YAML简单地写如下
rules:
- action:
count: {}
name: rulenumbertwo
priority: 123
statement:
bytematchstatement:
fieldtomatch:
singleheader:
name: foobar
positionalconstraint: CONTAINS
searchstring: fizzbuzz
或者可能使用模板(但为什么应该很容易(
searchstring: {{ convertStringToByteArray "fizzbuzz" }}
包含SearchString的类型ByteMatchStatement
上没有任何声明,因为它自定义了从YAML加载的方式,所以它不能从YAML标量加载[]byte
。您链接的手册描述了类型的语义,但既没有定义如何存储数据(根据用例,将string
存储为[]byte
对用户来说是有意义的(,也没有定义如何从YAML加载数据。通常,(反(序列化倾向于公开有关数据模型的事实,否则这些事实将是实现细节,这就是您在这里遇到的问题。
简单的修复方法是声明一些type SearchStringType []byte
,将其用于SearchString
字段,并在那里声明一个自定义UnmarshalYAML
方法来处理到[]byte
的转换。但是,这在您的代码中是不可能的,因为您无法控制类型。
一个可能的但有些粗糙的解决方案是预处理YAML输入:
type LoadableUpdateRuleGroupInput wafv2.UpdateRuleGroupInput
func (l *LoadableUpdateRuleGroupInput) UnmarshalYAML(n *yaml.Node) error {
preprocSearchString(n)
return n.Decode((*wafv2.UpdateRuleGroupInput)(l))
}
func preprocSearchString(n *yaml.Node) {
switch n.Kind {
case yaml.SequenceNode:
for _, item := range n.Content {
preprocSearchString(item)
}
case yaml.MappingNode:
for i := 0; i < len(n.Content); i += 2 {
if n.Content[i].Kind == yaml.ScalarNode &&
n.Content[i].Value == "searchstring" {
toByteSequence(n.Content[i+1])
} else {
preprocSearchString(n.Content[i+1])
}
}
}
}
func toByteSequence(n *yaml.Node) {
n.Kind = yaml.SequenceNode
raw := []byte(n.Value)
n.Content = make([]*yaml.Node, len(raw))
for i := range raw {
n.Content[i] = &yaml.Node{Kind: yaml.ScalarNode, Value: strconv.Itoa(int(raw[i]))}
}
}
通过在解组时使用这个新的子类型,searchstring
的YAML标量值将被转换为您编写的YAML序列节点。当您加载YAML节点时,它将正确地加载到[]byte
:中
d := &LoadableUpdateRuleGroupInput{}
err = yaml.Unmarshal(buf, d)
此代码需要gopkg.in/yaml.v3
,而v2
并不能为您提供对解组的控制。