Reputation: 118
I'll write "pseudo-python-jsonnet" code to show what I want to achieve. I really have no clue how to do something like that in 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
So basically I want to search a deep object structure for a specific sub-object and return it or return null/None if it is not found.
https://jsonnet.org/learning/tutorial.html is somehow good, but only shows the "easy" parts, if you want to do more complex things with jsonnet, it seems you're left on your own. I'm new to jsonnet and it really gives me headaches, so I hope someone can help me.
Upvotes: 0
Views: 911
Reputation: 3030
Below scriptlet implements it
// 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),
}
Although depending on your specific problem, you may want to look at https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/README.md#customising-alert-annotations for utils.mapRuleGroups()
approach (granted it rather mutates rule(s)).
Upvotes: 1