diff --git a/component/alert-routing-discovery.libsonnet b/component/alert-routing-discovery.libsonnet index 97519a03..b84d7845 100644 --- a/component/alert-routing-discovery.libsonnet +++ b/component/alert-routing-discovery.libsonnet @@ -2,6 +2,7 @@ local com = import 'lib/commodore.libjsonnet'; local kap = import 'lib/kapitan.libjsonnet'; local kube = import 'lib/kube.libjsonnet'; local prom = import 'lib/prom.libsonnet'; +local syn_teams = import 'syn/syn-teams.libsonnet'; local inv = kap.inventory(); local params = inv.parameters; @@ -25,7 +26,7 @@ local discoverNS = function(app) else if std.isObject(p.namespace) && std.objectHas(p.namespace, 'name') && std.isString(p.namespace.name) then p.namespace.name; - local ks = prom.appKeys(app); + local ks = syn_teams.appKeys(app); local aliased = f(ks[0]); if aliased != null then aliased @@ -44,7 +45,9 @@ local teamToNS = std.mapWithKey( function(_, a) std.uniq(std.sort(std.prune(a))), std.foldl( function(prev, app) - prev { [prom.teamForApplication(app)]+: [ discoverNS(app) ] }, + local instance = syn_teams.appKeys(app, true)[0]; + local team = syn_teams.teamForApplication(instance); + prev { [team]+: [ discoverNS(app) ] }, inv.applications, {} ) @@ -86,7 +89,7 @@ local alertmanagerConfig = debugConfigMap: kube.ConfigMap('discovery-debug') { data: { local discoveredNamespaces = std.foldl(function(prev, app) prev { [app]: discoverNS(app) }, inv.applications, {}), - local discoveredTeams = std.foldl(function(prev, app) prev { [app]: prom.teamForApplication(app) }, inv.applications, {}), + local discoveredTeams = std.foldl(function(prev, app) prev { [app]: syn_teams.teamForApplication(syn_teams.appKeys(app, true)[0]) }, inv.applications, {}), applications: std.manifestJsonMinified(inv.applications), discovered_namespaces: std.manifestYamlDoc(discoveredNamespaces), apps_without_namespaces: std.manifestYamlDoc(std.foldl(function(prev, app) if discoveredNamespaces[app] == null then prev + [ app ] else prev, std.objectFields(discoveredNamespaces), [])), diff --git a/jsonnetfile.jsonnet b/jsonnetfile.jsonnet index b71b6f22..3ae815e7 100644 --- a/jsonnetfile.jsonnet +++ b/jsonnetfile.jsonnet @@ -1,6 +1,16 @@ { version: 1, dependencies: std.prune([ + { + source: { + git: { + remote: 'https://github.com/projectsyn/jsonnet-libs', + subdir: '', + }, + }, + version: 'initial-implementation', + name: 'syn', + }, { source: { git: { diff --git a/lib/openshift4-monitoring-alert-patching.libsonnet b/lib/openshift4-monitoring-alert-patching.libsonnet index 637b4eb8..4c463419 100644 --- a/lib/openshift4-monitoring-alert-patching.libsonnet +++ b/lib/openshift4-monitoring-alert-patching.libsonnet @@ -2,7 +2,7 @@ // arbitrary alert rules to adhere to the format required by the component's // approach for allowing us to patch upstream rules. local com = import 'lib/commodore.libjsonnet'; -local prom = import 'lib/prom.libsonnet'; +local syn_teams = import 'syn/syn-teams.libsonnet'; local inv = com.inventory(); @@ -99,6 +99,9 @@ local filterRules(group, ignoreNames=[], preserveRecordingRules=false) = * \returns The patched rule */ local patchRule(rule, patches={}, patchName=true) = + local fallbackTeam = std.get(inv.parameters, 'syn', { + owner: inv.parameters.openshift4_monitoring.fallback_team, + }).owner; if !std.objectHas(rule, 'alert') then rule else @@ -113,7 +116,7 @@ local patchRule(rule, patches={}, patchName=true) = then rule.labels.syn_team else - prom.teamForApplication(inv.parameters._instance); + syn_teams.teamForApplication(inv.parameters._instance); rule { // Change alert names so we don't get multiple alerts with the same // name, as the logging operator deploys its own copy of these diff --git a/lib/openshift4-monitoring-prom.libsonnet b/lib/openshift4-monitoring-prom.libsonnet index 03681ffe..a7f9cc0e 100644 --- a/lib/openshift4-monitoring-prom.libsonnet +++ b/lib/openshift4-monitoring-prom.libsonnet @@ -4,13 +4,10 @@ * API reference: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md */ -local com = import 'lib/commodore.libjsonnet'; local kube = import 'lib/kube.libjsonnet'; local alertpatching = import 'lib/alert-patching.libsonnet'; -local inv = com.inventory(); - // Define Prometheus Operator API versions local api_version = { monitoring: 'monitoring.coreos.com/v1', @@ -57,81 +54,6 @@ local prometheusRule(name) = Alertmanager(name): kube._Object(api_version.monitoring, 'Alertmanager', name), - /** - * \brief Returns an array with the (aliased) application name and if aliased the original name in the second position. - * - * The application name is translated from kebab-case to snake_case, except if the second parameter is set to true. - * - * \arg name - * The application name. Can be `name` or `name as alias`. - * \arg raw - * If set to true, the application name is not translated from kebab-case to snake_case. - * \return - * An array with the (aliased) application name and if aliased the original name in the second position. - */ - appKeys: function(name, raw=false) - local normalized = function(name) if raw then name else std.strReplace(name, '-', '_'); - // can be simplified with jsonnet > 0.19 which would support ' as ' as the substring - local parts = std.split(name, ' '); - if std.length(parts) == 1 then - [ normalized(parts[0]) ] - else if std.length(parts) == 3 && parts[1] == 'as' then - [ normalized(parts[2]), normalized(parts[0]) ] - else - error 'invalid application name `%s`' % name, - - /** - * \brief Returns the team for the given application or null. - * - * It does so by looking at the top level syn parameter. - * The syn parameter should look roughly like this. - * - * syn: - * owner: clumsy-donkeys - * teams: - * chubby-cockroaches: - * instances: - * - superb-visualization - * lovable-lizards: - * instances: - * - apartment-cats - * - * The application is first looked up in the instances of the teams, if no team is found, owner is used as fallback. - * An error is thrown if the application is found belonging to multiple teams. - * - * \arg app - * The application name. Can be the merged `inventory().params._instance` or an (aliased) application name. - * \return - * The team name or `null` if no team is found. - */ - teamForApplication: function(app) - local params = inv.parameters; - local lookup = function(app) - if std.objectHas(params, 'syn') && std.objectHas(params.syn, 'teams') then - local teams = params.syn.teams; - local teamsForApp = std.foldl( - function(prev, team) - if std.objectHas(teams, team) && std.objectHas(teams[team], 'instances') && std.member(com.renderArray(teams[team].instances), app) then - prev + [ team ] - else - prev, - std.objectFields(teams), - [], - ); - if std.length(teamsForApp) == 0 then - null - else if std.length(teamsForApp) == 1 then - teamsForApp[0] - else - error 'application `%s` is in multiple teams: %s' % [ app, std.join(', ', teamsForApp) ]; - - local teams = std.prune(std.map(lookup, self.appKeys(app, true))); - - if std.length(teams) > 0 then - teams[0] - else if std.objectHas(params, 'syn') && std.objectHas(params.syn, 'owner') then - params.syn.owner, - /** * \brief Function to render rules defined in the hierarchy *