Skip to content

v0.25.0

Choose a tag to compare

@github-actions github-actions released this 11 Nov 16:18
· 5 commits to main since this release
Immutable release. Only release title and notes can be modified.
fd1bc5f

lapilli serve run by the people who use it
(docs/design/serveops.md): quiet windows every
month or by cron, and a team's own; the weekly digest set in the UI; roles
given in the UI, of every team or of one; the range check by each job's own
scrape interval; and Grafana's notification templates checked beside each
rule. Ledger schema 014: grants, and a quiet window's team and schedule;
nothing changes on upgrade until someone uses them.

  • Quiet windows every month or by a cron expression, beside every day
    and every week: every: month with on a day (15), last, or a
    weekday of the month (first sat, last fri), at the start's time of
    day; every: cron with on five cron fields, hourly at most. The first
    repeat is the window's start and end, and must be one of the schedule's
    times (a refusal names the next); each repeat is shorter than the
    shortest time between two over the four years from the start, a leap
    year's cycle. A firing is looked up once: in the last repeat to start by
    it, or by the end of Until's day, whatever the gap. Daylight saving is
    the reports' (internal/schedule, which also gains the weekday of a
    month for reports: monthly first sat@09:00).
  • A team's quiet window (team_id) excuses only the firings of rules
    the team owns, worked out in the ledger as the pages work it out; a
    change to who owns what judges every team's window again, and a team
    removed stops its windows, as it stops its reports. A window's page
    names the team of each firing it excused.
  • Who owns a rule is decided by its name first: a note's team, or else
    the first team, by name, whose pattern matches it, and only then the
    first whose labels it has. Before, the first team by name whose pattern
    or labels matched did, so a team owning by labels could take a rule
    another team's pattern named. Where teams overlap so, upgrading moves
    such a rule to the team its pattern names, and with it everything done
    by team: the rule's page and lists filtered by team, the teams' tallies
    and overview, its team's digest and reports, whose hours count its
    firings asleep or off hours, the incidents its catches give a team, and
    which team's editors may change its notes, tasks and quiet windows.
  • Roles given in the UI (/roles, from the Teams page, and
    /api/v1/roles), with --admins: an admin gives an editor's role, of
    every team or of one, to user:NAME or group:NAME. Never admin or
    approver (the table refuses any other role), never everyone, and a role
    the flags give can't be taken away. A team's editors change their team's
    tasks, quiet windows and reports (to the team's own destination), notes
    on rules it owns (keeping their team) and comments on what is its; the
    ledger checks each inside the write, before and after, so a row can't be
    moved between teams. Only admins see who holds a role; a role taken away
    stops at the next request; a team removed takes its editors with it;
    the runs page shows roles given and taken to admins alone. A team's
    editors make ten of its reports at most, and the last ten of the
    ledger's fifty are an admin's.
    GET /api/v1/me gives the teams the reader edits, and the pages offer
    each reader what they may.
  • The weekly digest set in the UI: on the Reports page and with GET,
    PUT and DELETE /api/v1/reports/digest. The flags define it until an
    admin sets it; from then on the ledger does, --digest isn't used (the
    log says so at start), and it can go to any named destination, a
    --report-dest too. It stays weekly, and its suggestions are worked out
    at its time whether it is sent or not. Upgrading changes nothing: the
    weeks sent are kept as before, so no week is sent twice and none is lost;
    a week due while it is off is passed over; moving its day never sends an
    older week. "Back to the flags" gives it back.
  • Reports of a team can be made by its editors and by editors, sent to
    the team's own destination (team:NAME); reports for everyone, or sent
    elsewhere, stay an admin's. A week of the digest sent isn't sent again
    to a destination added after it went; the digest is on the Reports page
    to set whenever a report can go anywhere.
  • The range check by each job's own scrape interval: serve and
    lapilli verdict --check-content read each job's scrape_interval from
    /api/v1/status/config and the job label its targets end up with from
    /api/v1/targets (a ServiceMonitor's job is its service's name). A range
    over a selector naming its job counts with that job's interval (the
    longest a job=~ can be); any other with the global, or the one every
    job has. The finding says whose: rate[3m] < 2 × 2m (job "batch").
    Checked against a real Prometheus 3.5.0.
  • Grafana's notification templates, with --grafana: its templates,
    contact points and notification policies, read once an hour through the
    provisioning API with the rules' token (a Viewer's reads them), 8 MB an
    answer, no redirects. A rule's notifications are written with the
    templates of its own contact point (notification_settings) or of those
    the policies route it to by its labels, alertname and
    grafana_folder; a matcher on a label the rule doesn't set is followed
    both ways, and a template counts only when every way uses it. Three new
    checks: notify_no_text (an annotation a template shows the rule
    hasn't; fact), notify_label_never_seen (measured) and
    notify_label_not_given (heuristic, by a rule's one query). Policies'
    match and match_re are read; a rule's label written as a template,
    and policies past the 2,000 or 32 levels read, route both ways or not at
    all; {{ or .x "fallback" }} is guarded. Contact points are numbered
    and a way's are a bitset; routing is charged by the work done, a
    million a rule and twenty million a check, rules alike in the labels the
    policies match on are routed once, and the check routes for five
    seconds at most: the 1,697-policy tree a real Grafana accepted gives
    each rule up in about 20 ms, and 500 rules take 0.3 s. A rule given up
    on says so on its page, and why, and the log says how many, once a
    check. Templates are parsed, never run. Checked against a real Grafana
    13.3.1.
  • Korean: quiet windows are 메인터넌스 윈도우, as DevOps teams say it.
  • Security (from before this batch): a name the sign-in proxy gave
    with a character that doesn't show (a zero-width space, a soft hyphen, a
    word joiner) had it taken out, so it could become another person's, an
    admin's. Such a name, or one over 200 bytes, is no one's now: it may
    only look. Refused are control characters; format characters, but the
    zero-width joiner and non-joiner between two letters of one script or
    two emoji, as Persian names and emoji use them; characters that show
    nothing on their own (the combining grapheme joiner, the Hangul
    fillers); and a variation selector but after a symbol. A grant's name
    is held to the same, 200 bytes.
  • The weekly digest's outbox guard read a key TellOnce didn't write,
    so from the second week every round worked the whole digest out again
    before finding it told (also in 0.23 and 0.24). It reads what TellOnce
    keeps, or the week 0.24 marked as passed over, when later.
  • Reviewed three times, once as an attacker would and twice for
    correctness and cost, then the fixes verified and what that found fixed
    too: no way to an admin's or an approver's role was found; what was found
    is in docs/design/serveops.md, "What the reviews found". Every refusal
    has a test, and each fix and key check, taken out, fails one. A ledger
    from 0.24 migrates to schema 014 with the same stones.