What I'm trying to do is create a libsonnet library with some complex validation on the inputs, but I'm not sure how to implement this in the libsonnet
file without getting null
back.
I'm trying to generate API calls for Hosted Graphite's Alerts API using Jsonnet. The idea being is that we can store all of our alerts in version control, and update them in a CI / CD pipeline. I want to prevent errors, so I've implemented some complex validation based on what the above API spec defines. I have the following saved as alerts.libsonnet
:
local alert_criteria_types = [
'above',
'below',
'missing',
'outside_bounds',
];
local notification_types_strings = [
'state_change',
];
local notification_types_arrays = [
'every',
'state_change',
];
local on_query_failure_types = [
'ignore',
'notify',
null,
];
{
local HostedGraphiteAlerts = self,
new(
name,
metric,
alert_criteria_type,
additional_alert_criteria={},
additional_criteria={},
expression='a',
scheduled_mutes=[],
notification_channels=['Email me'],
notification_type=null,
info=null,
on_query_failure='notify',
)::
// Simple checks
assert std.member(alert_criteria_types, alert_criteria_type) : "Input 'alert_criteria_type' is not one of the types: %s." % std.join(', ', alert_criteria_types);
assert std.member(on_query_failure_types, on_query_failure) : "Input 'on_query_failure_type' is not one of the types: %s." % std.join(', ', on_query_failure_types);
// Advanced checks
if notification_type != null && std.isString(notification_type) then
assert std.member(notification_types_strings, notification_type) : "Input 'notification_type' is not one of the types: %s." % std.join(', ', notification_types_strings);
if notification_type != null && std.isArray(notification_type) then
assert std.member(notification_types_arrays, notification_type[0]) : "Input 'notification_type' is not one of the types: %s." % std.join(', ', notification_types_arrays);
if notification_type != null && std.isArray(notification_type) then
assert std.member(notification_types_arrays, notification_type[0]) : "Input 'notification_type' is not one of the types: %s." % std.join(', ', notification_types_arrays);
if notification_type != null && std.isArray(notification_type) && notification_type[0] == 'every' then
assert notification_type[1] != null : "Input 'notification_type' cannot have an empty entry for 'time_in_minutes' for notification type 'every'.";
if notification_type != null && std.isArray(notification_type) && notification_type[0] == 'every' then
assert std.isNumber(notification_type[1]) : "Input 'notification_type' must have a JSON 'number' type for notification type 'every'.";
// Main
{
name: name,
metric: metric,
alert_criteria: {
type: alert_criteria_type,
} + additional_alert_criteria,
additional_criteria: additional_criteria,
expression: expression,
scheduled_mutes: scheduled_mutes,
notification_channels: notification_channels,
notification_type: notification_type,
info: info,
on_query_failure: on_query_failure,
},
}
This passes a basic jsonnetfmt
check, but the problem is when I go to use it in an alerts.jsonnet
file like so:
local alerts = (import 'hosted_graphite.libsonnet').alerts;
alerts.new(
name='something',
metric='some.graphite.metric',
alert_criteria_type='below',
)
This simply returns null
:
$ jsonnet hosted_graphite/alerts.jsonnet
null
I know this is because it's taking the value of the first assert
statement. But how else can this be done?
Thank you!