Fix PMG API parameter issues causing 400 errors

Related to #614

Corrects three issues with PMG monitoring:

1. Remove unsupported timeframe parameter from GetMailStatistics
   - PMG API /statistics/mail does not accept timeframe parameter
   - Previously sent "timeframe=day" causing 400 error
   - API returns current day statistics by default

2. Fix GetMailCount timespan parameter to use seconds
   - Changed from 24 (hours) to 86400 (seconds)
   - PMG API expects timespan in seconds, not hours
   - Previously sent "timespan=24" causing 400 error

3. Update function signature and tests
   - Renamed GetMailCount parameter from timespanHours to timespanSeconds
   - Updated test expectations to match corrected API calls
   - Tests verify parameters are sent correctly

These changes align the PMG client with actual PMG API requirements,
fixing the data population issues reported in v4.25.0.
This commit is contained in:
rcourtman 2025-11-05 19:28:37 +00:00
parent fcba710183
commit 4c1d7a2797
3 changed files with 11 additions and 16 deletions

View file

@ -7467,7 +7467,7 @@ func (m *Monitor) pollPMGInstance(ctx context.Context, instanceName string, clie
Msg("PMG backups polled")
}
if stats, err := client.GetMailStatistics(ctx, "day"); err != nil {
if stats, err := client.GetMailStatistics(ctx, ""); err != nil {
log.Warn().Err(err).Str("instance", instanceName).Msg("Failed to fetch PMG mail statistics")
} else if stats != nil {
pmgInst.MailStats = &models.PMGMailStats{
@ -7492,7 +7492,7 @@ func (m *Monitor) pollPMGInstance(ctx context.Context, instanceName string, clie
}
}
if counts, err := client.GetMailCount(ctx, 24); err != nil {
if counts, err := client.GetMailCount(ctx, 86400); err != nil {
if debugEnabled {
log.Debug().Err(err).Str("instance", instanceName).Msg("Failed to fetch PMG mail count data")
}

View file

@ -35,15 +35,13 @@ func TestPollPMGInstancePopulatesState(t *testing.T) {
fmt.Fprint(w, `{"data":[{"cid":1,"name":"mail-gateway","type":"master","ip":"10.0.0.1"}]}`)
case "/api2/json/statistics/mail":
if r.URL.Query().Get("timeframe") != "day" {
t.Fatalf("expected timeframe=day, got %s", r.URL.RawQuery)
}
// PMG API does not accept timeframe parameter
w.Header().Set("Content-Type", "application/json")
fmt.Fprint(w, `{"data":{"count":100,"count_in":60,"count_out":40,"spamcount_in":5,"spamcount_out":2,"viruscount_in":1,"viruscount_out":0,"bounces_in":3,"bounces_out":1,"bytes_in":12345,"bytes_out":54321,"glcount":7,"junk_in":4,"avptime":0.5,"rbl_rejects":2,"pregreet_rejects":1}}`)
case "/api2/json/statistics/mailcount":
if r.URL.Query().Get("timespan") != "24" {
t.Fatalf("expected timespan=24, got %s", r.URL.RawQuery)
if r.URL.Query().Get("timespan") != "86400" {
t.Fatalf("expected timespan=86400 (24 hours in seconds), got %s", r.URL.RawQuery)
}
now := time.Now().Unix()
w.Header().Set("Content-Type", "application/json")

View file

@ -404,22 +404,19 @@ func (c *Client) GetVersion(ctx context.Context) (*VersionInfo, error) {
}
func (c *Client) GetMailStatistics(ctx context.Context, timeframe string) (*MailStatistics, error) {
params := url.Values{}
if timeframe != "" {
params.Set("timeframe", timeframe)
}
// PMG API does not accept timeframe parameter - it returns current day statistics
// The timeframe parameter is ignored to maintain API compatibility
var resp apiResponse[MailStatistics]
if err := c.getJSON(ctx, "/statistics/mail", params, &resp); err != nil {
if err := c.getJSON(ctx, "/statistics/mail", nil, &resp); err != nil {
return nil, err
}
return &resp.Data, nil
}
func (c *Client) GetMailCount(ctx context.Context, timespanHours int) ([]MailCountEntry, error) {
func (c *Client) GetMailCount(ctx context.Context, timespanSeconds int) ([]MailCountEntry, error) {
params := url.Values{}
if timespanHours > 0 {
params.Set("timespan", fmt.Sprintf("%d", timespanHours))
if timespanSeconds > 0 {
params.Set("timespan", fmt.Sprintf("%d", timespanSeconds))
}
var resp apiResponse[[]MailCountEntry]