在(深)对象中查找并 return 元素

Find and return element in (deep) object

我将编写“伪-python-jsonnet”代码来展示我想要实现的目标。 我真的不知道如何在 jsonnet 中做类似的事情。

local createCopy(gname, rname, kp) =                                        
    for topLvlKey in std.objectFieldsAll(kp):                                   
        for subKey in std.objectFieldsAll(kp[topLvlKey]):                       
            if kp[topLvlKey][subKey].get("kind", "") == "PrometheusRule":       
                for group in kp[topLvlKey][subKey]["spec"]["groups"]:           
                    if group["name"] == gname:                              
                        for rule in group["rules"]:                             
                            if rule.get("alert", "") == rname:              
                                return rule
                        return null                                    
    return null 

所以基本上我想搜索一个特定子对象的深层对象结构,如果找不到它 return 或 return null/None。

https://jsonnet.org/learning/tutorial.html 有点不错,但只显示了“简单”的部分,如果你想用 jsonnet 做更复杂的事情,看来你只能靠自己了。我是jsonnet的新手,它真的让我很头疼,所以我希望有人能帮助我。

下面的脚本实现了它

// filterArray by func() (returning bool)
local filterArray(array, func) = [elem for elem in array if func(elem)];

// search Prometheus' rule groups by groupName, alertName
local getPrometheusRule(groups, groupName, alertName) = (
  local group = filterArray(groups, function(x) std.objectHas(x, 'name') && x.name == groupName);
  if std.length(group) > 0
  then (
    assert std.length(group) == 1 : 'Duplicated group.name "%s"' % groupName;
    local rule = filterArray(group[0].rules, function(x) std.objectHas(x, 'alert') && x.alert == alertName);
    if std.length(rule) > 0
    then (
      assert std.length(rule) == 1 : 'Duplicated alert "%s"' % alertName;
      rule[0]
    )
  )
);

local createCopy(gname, rname, kp) = [
  if std.objectHas(kp[topLvlKey][subKey], 'kind') && kp[topLvlKey][subKey].kind == 'PrometheusRule'
  then getPrometheusRule(kp[topLvlKey][subKey].spec.groups, gname, rname)
  for topLvlKey in std.objectFieldsAll(kp)
  for subKey in std.objectFieldsAll(kp[topLvlKey])
];

/* Simple unit-tests follow */

local stack = {
  fooService: {
    fooResource: {
      kind: 'PrometheusRule',
      spec: {
        groups: [
          { name: 'fooGroup', rules: [{ alert: 'fooAlert', expr: 'fooExpr' }] },
          { name: 'barGroup', rules: [{ alert: 'fooAlert', expr: 'fooExpr' }] },
        ],
      },
    },
  },
};

{
  test_01_Found: createCopy('fooGroup', 'fooAlert', stack),
  test_02_NotFound: createCopy('fooGroup', 'fooAlerX', stack),
  test_03_NotFound: createCopy('fooGrouX', 'fooAlert', stack),
}

尽管根据您的具体 问题 ,您可能希望查看 https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/README.md#customising-alert-annotationsutils.mapRuleGroups() 方法(假设它而不是 突变 条规则。