feat(11-04): add the websockets health, VAPID key and test-push commands

- centrifugo.Client.Info probes the info API method; an error body fails
- websockets:health ports CentrifugoHealthCheck: exits 1 without an API
  key or when the probe fails, prints the Setting/Value table otherwise
- websockets:generate-vapid-keys prints a new P-256 pair, shows configured
  keys only truncated, and --update persists them to overrides.yaml
- websockets:test-push reads subscriptions from an app-published
  SubscriptionSource, refuses to send while push is disabled and sends
  one encrypted push per subscription
- no command prints a configured private key or the Centrifugo API key
- flare and lighthouse READMEs document the CLI commands
This commit is contained in:
Jakub Zych
2026-09-30 13:52:44 +02:00
parent 5fb22c28d0
commit f55cb444ab
7 changed files with 1057 additions and 3 deletions

View File

@@ -158,6 +158,37 @@ func (c *Client) Unsubscribe(ctx context.Context, userID uint, channel string) e
return err
}
// Info POSTs {} to {api_url}/info and returns its result: Centrifugo's node
// list and statistics. It is the connectivity probe of websockets:health.
// Unlike the publishing calls, an answer with an error body is an error.
func (c *Client) Info(ctx context.Context) (map[string]any, error) {
out := map[string]any{}
if !c.Enabled() {
return out, ErrNotConfigured
}
raw, err := c.post(ctx, "/info", struct{}{})
if err != nil {
return out, err
}
var resp struct {
Error *struct {
Code int `json:"code"`
Message string `json:"message"`
} `json:"error"`
Result map[string]any `json:"result"`
}
if err := json.Unmarshal(raw, &resp); err != nil {
return out, fmt.Errorf("centrifugo: /info: response is not JSON")
}
if resp.Error != nil {
return out, fmt.Errorf("centrifugo: /info: error %d: %s", resp.Error.Code, resp.Error.Message)
}
if resp.Result != nil {
out = resp.Result
}
return out, nil
}
func (c *Client) data(event string, payload json.RawMessage) eventData {
if len(bytes.TrimSpace(payload)) == 0 {
payload = json.RawMessage("[]")