我应该如何在YAML中编写和解组字节64编码的值



我的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并不能为您提供对解组的控制。

最新更新