Repository navigation
v0.25.0
·
5 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
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: monthwithona day (15),last, or a
weekday of the month (first sat,last fri), at the start's time of
day;every: cronwithonfive 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, touser:NAMEorgroup: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/megives 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,
PUTandDELETE /api/v1/reports/digest. The flags define it until an
admin sets it; from then on the ledger does,--digestisn't used (the
log says so at start), and it can go to any named destination, a
--report-desttoo. 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:
serveand
lapilli verdict --check-contentread each job'sscrape_intervalfrom
/api/v1/status/configand 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 ajob=~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,alertnameand
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'
matchandmatch_reare 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.