Answer AST name queries for the source fact on /facts
This commit is contained in:
@@ -387,7 +387,54 @@ func (s *Server) serveUnion(w http.ResponseWriter, r *http.Request, path string,
|
||||
}
|
||||
|
||||
func (s *Server) serveFacts(w http.ResponseWriter, r *http.Request) {
|
||||
s.serveMerged(w, r, factsPath, s.mergeFactsResponse(r))
|
||||
query := r.URL.Query().Get("query")
|
||||
inject := s.newSourceInjector(query, true)
|
||||
if ast := inject.sourceQuery(query); ast != nil {
|
||||
s.serveSourceFactQuery(w, r, inject, ast)
|
||||
return
|
||||
}
|
||||
s.serveMerged(w, r, factsPath, s.mergeFactsWith(inject))
|
||||
}
|
||||
|
||||
// serveSourceFactQuery answers a /facts query that selects the owned fact by
|
||||
// name. The query still goes upstream for the real facts it selects; the
|
||||
// synthetic records come from the same merge serveSourceFact uses and are
|
||||
// filtered by the query locally, since no backend holds them.
|
||||
func (s *Server) serveSourceFactQuery(w http.ResponseWriter, r *http.Request, inject *sourceInjector, ast []json.RawMessage) {
|
||||
params := queryParams(r.URL.Query().Get("query"))
|
||||
s.serveCached(w, r, factsPath, params, func(ctx context.Context) (cachedResponse, error) {
|
||||
alive, err := s.aliveResults(ctx, factsPath, params)
|
||||
if err != nil {
|
||||
return cachedResponse{}, err
|
||||
}
|
||||
recs := s.mergeFactsWith(inject)(alive)
|
||||
synth, _, err := s.sourceFacts(ctx, s.newSourceInjector("", true), nil)
|
||||
if err != nil {
|
||||
return cachedResponse{}, err
|
||||
}
|
||||
for _, raw := range synth {
|
||||
var f factFields
|
||||
if json.Unmarshal(raw, &f) != nil {
|
||||
continue
|
||||
}
|
||||
if match, _ := matchFact(ast, f); match {
|
||||
recs = append(recs, raw)
|
||||
}
|
||||
}
|
||||
resp := cachedResponse{Body: encodeRecords(recs), Records: -1}
|
||||
s.countBackends(&resp, alive)
|
||||
return resp, nil
|
||||
})
|
||||
}
|
||||
|
||||
// sourceFacts is the owned fact's synthetic record set for the nodes params
|
||||
// selects, taken from the /facts merge so owner and environment match it.
|
||||
func (s *Server) sourceFacts(ctx context.Context, inject *sourceInjector, params url.Values) ([]json.RawMessage, []backendResult, error) {
|
||||
alive, err := s.aliveResults(ctx, factsPath, params)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return sourceFactRecords(s.mergeFactsWith(inject)(alive), inject.name, "", false), alive, nil
|
||||
}
|
||||
|
||||
// Both path forms are the facts entity with a name (and value) constraint ANDed
|
||||
@@ -427,7 +474,6 @@ func (s *Server) serveSourceFact(w http.ResponseWriter, r *http.Request, inject
|
||||
}
|
||||
|
||||
params := queryParams(r.URL.Query().Get("query"))
|
||||
merge := s.mergeFactsWith(inject)
|
||||
var filter recordFilter
|
||||
if valued {
|
||||
filter = func(recs []json.RawMessage) []json.RawMessage {
|
||||
@@ -437,11 +483,10 @@ func (s *Server) serveSourceFact(w http.ResponseWriter, r *http.Request, inject
|
||||
// The stored set is the whole owned-fact record set, so every value of it
|
||||
// keys, and waits on, the same fetch.
|
||||
s.serveFiltered(w, r, factsPath+"/"+inject.name, params, filter, func(ctx context.Context) (cachedResponse, error) {
|
||||
alive, err := s.aliveResults(ctx, factsPath, params)
|
||||
recs, alive, err := s.sourceFacts(ctx, inject, params)
|
||||
if err != nil {
|
||||
return cachedResponse{}, err
|
||||
}
|
||||
recs := sourceFactRecords(merge(alive), inject.name, "", false)
|
||||
resp := cachedResponse{Body: encodeRecords(recs), Records: -1}
|
||||
s.countBackends(&resp, alive)
|
||||
return resp, nil
|
||||
@@ -766,10 +811,6 @@ func (s *Server) mergeNodesResponse(r *http.Request) func([]backendResult) []jso
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) mergeFactsResponse(r *http.Request) func([]backendResult) []json.RawMessage {
|
||||
return s.mergeFactsWith(s.newSourceInjector(r.URL.Query().Get("query"), true))
|
||||
}
|
||||
|
||||
// The path segment of /facts/<name> is the same outer `name` constraint the
|
||||
// query gate already rules injection out on, so nothing is synthesised here:
|
||||
// the source fact's own path is diverted to serveSourceFact before this.
|
||||
|
||||
Reference in New Issue
Block a user