Generalize `in` operator to work on strings and arrays
In Python in operator can be used to check if a value is an element of an array or if a string is a substring of another string. It's handy, the syntax is elegant and actually I was a bit surprised it doesn't work this way already.
@sparkprime Is there a specific reason for current behavior?
@camh- @chancez
yes there is a specific reason: laziness
That's an ambiguous response. I spent a whole 30 seconds trying to figure out how lazy evaluation would be impacted by this feature and I couldn't. Then I realised you were not referring to lazy evaluation, but human laziness.
Apologies, I was tired :)
Indeed it has nothing to do with lazy execution.
Hello there, is there any workaround to the lack of this support?
I'm trying to run a script that contains this snippet, but it fails since I can't check if an array contains a certain string with in:
local criticalAlerts = [
'KubePodCrashLooping',
];
local warningAlerts = [
'KubeStateMetricsListErrors',
];
local infoAlerts = [
'Watchdog',
];
local kp =
(import 'kube-prometheus/main.libsonnet') +
{
values+:: {
common+: {
namespace: std.extVar('namespace'),
},
},
kubernetesControlPlane+: {
prometheusRule+: {
spec+: {
groups: std.map(
function(group) group {
rules: std.map(
function(rule)
if 'alert' in rule && (rule.alert in criticalAlerts) then
rule { labels+: { severity: 'critical' } }
else if 'alert' in rule && (rule.alert in warningAlerts) then
rule { labels+: { severity: 'warning' } }
else if 'alert' in rule && (rule.alert in infoAlerts) then
rule { labels+: { severity: 'info' } }
else
rule,
super.rules
),
},
super.groups
),
},
},
},
}
;
EDIT: In case someone is also looking for a workaround, got that going with a map:
local alertSeverityMap = {
KubePodCrashLooping: 'critical',
KubeStateMetricsListErrors: 'warning',
Watchdog: 'info',
};
local kp =
(import 'kube-prometheus/main.libsonnet') +
{
values+:: {
common+: {
namespace: std.extVar('namespace'),
},
},
kubernetesControlPlane+: {
prometheusRule+: {
spec+: {
groups: std.map(
function(group) group {
rules: std.map(
function(rule)
if 'alert' in rule && (rule.alert in alertSeverityMap) then
rule { labels+: { severity: alertSeverityMap[rule.alert] } }
else
rule,
super.rules
),
},
super.groups
),
},
},
},
};
A more direct way is to use std.findSubstr for strings and std.member for checking array membership. We already have the functions we need. This is just about more obvious / direct syntax.