Files
karma/internal/mapper/v015/status.go
2019-09-14 12:34:52 +01:00

93 lines
2.3 KiB
Go

package v015
import (
"encoding/json"
"errors"
"fmt"
"io"
"github.com/Masterminds/semver/v3"
"github.com/prymitive/karma/internal/mapper"
"github.com/prymitive/karma/internal/models"
"github.com/prymitive/karma/internal/uri"
)
type clusterPeer struct {
Address string `json:"address"`
Name string `json:"name"`
}
type clusterStatus struct {
Name string `json:"name"`
Peers []clusterPeer `json:"peers"`
Status string `json:"status"`
}
type alertmanagerStatusResponse struct {
Status string `json:"status"`
Data struct {
VersionInfo struct {
Version string `json:"version"`
} `json:"versionInfo"`
ClusterStatus clusterStatus `json:"clusterStatus"`
} `json:"data"`
}
// StatusMapper implements Alertmanager API schema
type StatusMapper struct {
mapper.StatusMapper
}
// AbsoluteURL for status API endpoint this mapper supports
func (s StatusMapper) AbsoluteURL(baseURI string) (string, error) {
return uri.JoinURL(baseURI, "api/v1/status")
}
// QueryArgs for HTTP requests send to the Alertmanager API endpoint
func (s StatusMapper) QueryArgs() string {
return ""
}
// IsSupported returns true if given version string is supported
func (s StatusMapper) IsSupported(version string) bool {
versionRange, err := semver.NewConstraint(">=0.15.0, <0.16.0")
if err != nil {
panic(err)
}
return versionRange.Check(semver.MustParse(version))
}
// IsOpenAPI returns true is remote Alertmanager uses OpenAPI
func (s StatusMapper) IsOpenAPI() bool {
return false
}
// Decode Alertmanager API response body and return karma model instances
func (s StatusMapper) Decode(source io.ReadCloser) (models.AlertmanagerStatus, error) {
status := models.AlertmanagerStatus{}
resp := alertmanagerStatusResponse{}
defer source.Close()
err := json.NewDecoder(source).Decode(&resp)
if err != nil {
return status, err
}
if resp.Status != mapper.AlertmanagerStatusString {
return status, fmt.Errorf("status endpoint returned status value '%s'", resp.Status)
}
if resp.Data.VersionInfo.Version == "" {
return status, errors.New("no version information in Alertmanager status API")
}
status.Version = resp.Data.VersionInfo.Version
status.ID = resp.Data.ClusterStatus.Name
for _, peer := range resp.Data.ClusterStatus.Peers {
status.PeerIDs = append(status.PeerIDs, peer.Name)
}
return status, nil
}