Conversation
a2c1576 to
f8ab539
Compare
|
Rebased onto latest |
|
CI is green now — thanks for approving the run. The branch is rebased on main and still merges cleanly. Locally Could a maintainer take a look when there's time? |
|
It feels so strange to send a Flux alert to a social network 🤔 🤔 🤔 |
Mastodon can be used like Slack, but self-hosted and private. |
Add the mastodon Provider type for posting Flux events as statuses on a Mastodon account. Events are published with a plain HTTP POST to the /api/v1/statuses endpoint of the server given in the address, using an OAuth access token with the write:statuses scope as a bearer token. The status text carries a severity emoji, the involved object, the event message and the event metadata as key-value lines in sorted key order, truncated to the 500-character default server limit. An Idempotency-Key header derived from the event guards against duplicate statuses when the HTTP client retries a request whose response was lost. An optional visibility query parameter on the address maps to the status visibility field, since the Provider API has no dedicated field for it. Assisted-by: Claude Code/claude-fable-5 Signed-off-by: Chose Carreras <xchose@gmail.com>
Carrying the status visibility as a query parameter on the Provider address was an ad hoc convention that could be mistaken for a parameter accepted by the Mastodon server. Remove it and leave the visibility field out of the payload, so statuses are posted with the default posting privacy configured on the account. A dedicated Provider input can be added later once there is a generic mechanism for provider specific settings. Signed-off-by: Martin Cholewa <xchose@gmail.com> Assisted-by: Claude Code/claude-fable-5-1
The Mastodon provider computed its own idempotency key from the object UID, reason, timestamp and status text, giving an event a second identity next to the one the event server already uses for rate limiting. Move the key computation from the event server into notifier.EventKey and pass the key to notifiers through the context. The notifier cannot recompute it from the event it receives, because the token metadata is removed and the group prefix of the revision keys is stripped before dispatch. The Mastodon provider now sends that key and falls back to deriving it from the event when called outside the event server. Mastodon keeps idempotency keys for one hour, so identical events within that window yield a single status. This is documented in the spec. Signed-off-by: Martin Cholewa <xchose@gmail.com> Assisted-by: Claude Code/claude-fable-5-1
The setting lives under Preferences → Posting defaults and the Mastodon web interface names the unlisted visibility Quiet public. Signed-off-by: Martin Cholewa <xchose@gmail.com> Assisted-by: Claude Code/claude-fable-5-1
Compute the event key in eventMiddleware and store it in the request context, so the rate limiter and the notifiers share one identity by construction instead of hashing the event twice per request. Drop the Mastodon fallback that derived the key from the event, since the notifier only sees the alert-mutated copy and the result could not match the rate limiter key. Without a key in the context no Idempotency-Key header is sent. Add the mastodon type to the provider API server validation test and restore the alphabetical order of the provider table in the spec. Signed-off-by: Martin Cholewa <xchose@gmail.com> Assisted-by: Claude Code/claude-fable-5-1
a1ba19c to
08e336e
Compare
|
Rebased on main, review comments addressed. Could a maintainer approve the CI run? |
The event key was forwarded from the request context into the notifier's context in dispatchNotification and read back inside Mastodon.Post, unlike every other notifier input which is wired through getNotificationParams and createNotifier. Read the key computed by eventMiddleware in getNotificationParams, before the event is mutated, and hand it to createNotifier as a notifier option. The Mastodon notifier stores it at construction and sends it as the Idempotency-Key header. The context helpers in the notifier package are removed; the key stays in the request context only within the event server, where the middleware computes it once for the rate limiter. Signed-off-by: Martin Cholewa <xchose@gmail.com> Assisted-by: Claude Code/claude-fable-5-1
|
Review comment addressed in f7358bd, the event key is wired through Re-ran the e2e on kind against a real mastodon.social account with this change: |
matheuscscp
left a comment
There was a problem hiding this comment.
One last round and we should be good 🙏
createNotifier already receives the request context, so it can pick up the event key stored there by eventMiddleware itself instead of having getNotificationParams pass it down. Drop the fallback that recomputed the key from the event: the event metadata is mutated while the request is processed, so a recomputed key would not match the one used by the rate limiter, and the key is always present in the context anyway. Signed-off-by: Martin Cholewa <xchose@gmail.com> Assisted-by: Claude Code/claude-fable-5-1
|
Thanks @matheuscscp for the thorough review, I learned a lot about how the event server and the notifiers fit together. |




Fixes #447
Adds a
mastodonProvider type for posting Flux events as statuses on a Mastodon account, via a plain HTTPPOSTto the/api/v1/statusesendpoint. No SDK dependency; like every other notifier it only needs the sharedpostMessageclient.Implementation
addressis the server root URL (e.g.https://mastodon.social); the/api/v1/statusespath is appended automatically (and preserved if already present).write:statusesscope (Secret keytoken), sent as a bearer token.💫/🚨, same convention as the Telegram provider), involved objectkind/name.namespace, event message, and event metadata as key-value lines. Truncated to 500 characters, the default Mastodon server limit.status. Visibility follows the account's default posting visibility (Preferences → Posting defaults); "Quiet public" or "Followers only" is recommended for alert accounts and documented in the spec.Idempotency-Keyheader carries the event key the event server already uses for rate limiting. The key computation moved fromeventKeyFunctonotifier.EventKey, is computed once ineventMiddlewareand passed to notifiers through the context (the notifier cannot recompute it, since the token metadata is stripped before dispatch). Mastodon keeps the key for one hour, so retried requests and identical events within that window do not create additional statuses.Sample rendered payload:
{ "status": "💫 gitrepository/podinfo.flux-system\nstored artifact for commit 'master@sha1:3e0ff8a...'\n\nrevision: master@sha1:3e0ff8a..." }Testing
internal/notifier/mastodon_test.go: endpoint path, bearer auth header,Idempotency-Keytaken from the context and omitted without it, payload shape withoutvisibility, severity emoji, 500-char truncation, sorted metadata, path preservation and constructor validation against anhttptestserver.internal/notifier/eventkey_test.go: key stability and context round-trip.internal/controller/provider_controller_test.go: themastodontype is accepted by the API server.make tidy fmt vet generate manifests api-docsleave a clean tree.Manual e2e testing
kind cluster, controller image and CRD from this branch, real mastodon.social account. Secret:
address: https://mastodon.social,tokenwithwrite:statuses. Verified against an in-cluster echo server and then against mastodon.social:{"status": ...}only,Idempotency-Keyequals the rate-limiter digest recomputed by hand and is stable across identical events;GitRepositoryposted three statuses without errors;publicbefore changing the account setting andunlistedafter switching it to "Quiet public";🤖 Generated with Claude Code