Serve PuppetDB meta and metrics endpoints, sum node and resource counts
## Why Puppetboard 7.0.1 cannot run against pdbmux: it exits at import when /pdb/meta/v1/version 404s, and its landing page, metrics and radiator views 404 on the Jolokia surface. ## How - Serve /pdb/meta/v1/version, reporting the lowest version any backend runs, and /pdb/meta/v1/server-time from the first reachable backend. - Merge the Jolokia surface (/metrics/v2/read, /metrics/v2/list, /metrics/v1/mbeans): objects union, numeric attributes sum by default, and Min/Max/Uptime/StartTime plus the distribution stats take a bound or a mean. - Route /nodes extract-count queries to the summing path ahead of the certname merge, and give /resources aggregates the same path. - Document the endpoints and merge semantics in the README. - Cover version disagreement, metric rules, escaped MBean names, count summing and the non-aggregate /nodes merge with httptest backends.
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
const (
|
||||
factsPath = "/pdb/query/v4/facts"
|
||||
nodesPath = "/pdb/query/v4/nodes"
|
||||
resourcesPath = "/pdb/query/v4/resources"
|
||||
reportsPath = "/pdb/query/v4/reports"
|
||||
eventsPath = "/pdb/query/v4/events"
|
||||
eventCountsPath = "/pdb/query/v4/event-counts"
|
||||
@@ -57,6 +58,9 @@ func (s *Server) Handler() http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/healthz", s.handleHealth)
|
||||
mux.HandleFunc("/pdb/query/v4/", s.handleQuery)
|
||||
mux.HandleFunc(metaVersionPath, s.handleMetaVersion)
|
||||
mux.HandleFunc(metaServerTimePath, s.handleMetaServerTime)
|
||||
mux.HandleFunc(metricsPrefix, s.handleMetrics)
|
||||
return mux
|
||||
}
|
||||
|
||||
@@ -67,7 +71,9 @@ func (s *Server) handleQuery(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
switch r.URL.Path {
|
||||
case nodesPath:
|
||||
s.serveMerged(w, r, nodesPath, s.mergeNodesResponse)
|
||||
s.serveNodes(w, r)
|
||||
case resourcesPath:
|
||||
s.serveResources(w, r)
|
||||
case factsPath:
|
||||
s.serveMerged(w, r, factsPath, s.mergeFactsResponse)
|
||||
case reportsPath:
|
||||
@@ -134,6 +140,24 @@ func (s *Server) serveUnion(w http.ResponseWriter, r *http.Request, path string,
|
||||
writeJSON(w, page.apply(merged))
|
||||
}
|
||||
|
||||
// A count row carries no certname, so the certname-keyed merge would collapse every backend's count into one backend's; aggregates take the summing path instead.
|
||||
func (s *Server) serveNodes(w http.ResponseWriter, r *http.Request) {
|
||||
if spec := parseAggregate(r.URL.Query().Get("query")); spec != nil {
|
||||
s.serveSummed(w, r, nodesPath, spec.columns)
|
||||
return
|
||||
}
|
||||
s.serveMerged(w, r, nodesPath, s.mergeNodesResponse)
|
||||
}
|
||||
|
||||
// Only aggregates merge: a resource record has no cross-backend identity to dedupe on, so a plain query stays on the pass-through path.
|
||||
func (s *Server) serveResources(w http.ResponseWriter, r *http.Request) {
|
||||
if spec := parseAggregate(r.URL.Query().Get("query")); spec != nil {
|
||||
s.serveSummed(w, r, resourcesPath, spec.columns)
|
||||
return
|
||||
}
|
||||
s.proxyUnmerged(w, r)
|
||||
}
|
||||
|
||||
// An `extract` query with a `function` column returns synthetic aggregate rows that carry no identity, so they are summed rather than unioned.
|
||||
func (s *Server) serveReports(w http.ResponseWriter, r *http.Request) {
|
||||
if spec := parseAggregate(r.URL.Query().Get("query")); spec != nil {
|
||||
|
||||
Reference in New Issue
Block a user