diff --git a/admin/handlers/post.go b/admin/handlers/post.go index 7322b2a3..502bfb7c 100644 --- a/admin/handlers/post.go +++ b/admin/handlers/post.go @@ -156,17 +156,17 @@ func (h *HandlersAdmin) QueryRunPOSTHandler(w http.ResponseWriter, r *http.Reque adminErrorResponse(w, "error creating query", http.StatusInternalServerError, err) return } - - // List all the nodes that match the query - var expected []uint - - targetNodesID := []uint{} - // TODO: Refactor this to use osctrl-api instead of direct DB queries + // Temporary list of UUIDs to calculate Expected + var expected []string // Create environment target if len(q.Environments) > 0 { - expected = []uint{} for _, e := range q.Environments { if (e != "") && h.Envs.Exists(e) { + if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetEnvironment, e); err != nil { + adminErrorResponse(w, "error creating query environment target", http.StatusInternalServerError, err) + h.Inc(metricAdminErr) + return + } nodes, err := h.Nodes.GetByEnv(e, "active", h.Settings.InactiveHours(settings.NoEnvironmentID)) if err != nil { adminErrorResponse(w, "error getting nodes by environment", http.StatusInternalServerError, err) @@ -174,18 +174,21 @@ func (h *HandlersAdmin) QueryRunPOSTHandler(w http.ResponseWriter, r *http.Reque return } for _, n := range nodes { - expected = append(expected, n.ID) + expected = append(expected, n.UUID) } } } - targetNodesID = utils.Intersect(targetNodesID, expected) } // Create platform target if len(q.Platforms) > 0 { - expected = []uint{} platforms, _ := h.Nodes.GetAllPlatforms() for _, p := range q.Platforms { if (p != "") && checkValidPlatform(platforms, p) { + if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetPlatform, p); err != nil { + adminErrorResponse(w, "error creating query platform target", http.StatusInternalServerError, err) + h.Inc(metricAdminErr) + return + } nodes, err := h.Nodes.GetByPlatform(p, "active", h.Settings.InactiveHours(settings.NoEnvironmentID)) if err != nil { adminErrorResponse(w, "error getting nodes by platform", http.StatusInternalServerError, err) @@ -193,53 +196,60 @@ func (h *HandlersAdmin) QueryRunPOSTHandler(w http.ResponseWriter, r *http.Reque return } for _, n := range nodes { - expected = append(expected, n.ID) + expected = append(expected, n.UUID) } } } - targetNodesID = utils.Intersect(targetNodesID, expected) } // Create UUIDs target if len(q.UUIDs) > 0 { - expected = []uint{} for _, u := range q.UUIDs { - if u != "" { - node, err := h.Nodes.GetByUUID(u) - if err != nil { - log.Err(err).Msgf("error getting node %s and failed to create node query for it", u) - continue + if (u != "") && h.Nodes.CheckByUUID(u) { + if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetUUID, u); err != nil { + adminErrorResponse(w, "error creating query UUID target", http.StatusInternalServerError, err) + h.Inc(metricAdminErr) + return } - expected = append(expected, node.ID) + expected = append(expected, u) } } - targetNodesID = utils.Intersect(targetNodesID, expected) } // Create hostnames target if len(q.Hosts) > 0 { - expected = []uint{} for _, _h := range q.Hosts { - if _h != "" { - node, err := h.Nodes.GetByIdentifier(_h) - if err != nil { - log.Err(err).Msgf("error getting node %s and failed to create node query for it", _h) - continue + if (_h != "") && h.Nodes.CheckByHost(_h) { + if err := h.Queries.CreateTarget(newQuery.Name, queries.QueryTargetLocalname, _h); err != nil { + adminErrorResponse(w, "error creating query hostname target", http.StatusInternalServerError, err) + h.Inc(metricAdminErr) + return } - expected = append(expected, node.ID) + expected = append(expected, _h) } } - targetNodesID = utils.Intersect(targetNodesID, expected) } + // Remove duplicates from expected + expectedClear := removeStringDuplicates(expected) + // Create new record for query list + nodesID := make([]uint, len(expectedClear)) + for _, nodeUUID := range expectedClear { + node, err := h.Nodes.GetByUUID(nodeUUID) + if err != nil { + log.Err(err).Msgf("error getting node %s and failed to create node query for it", nodeUUID) + continue + } + nodesID = append(nodesID, node.ID) + } // If the list is empty, we don't need to create node queries - if len(targetNodesID) != 0 { - if err := h.Queries.CreateNodeQueries(targetNodesID, newQuery.ID); err != nil { + if len(nodesID) != 0 { + if err := h.Queries.CreateNodeQueries(nodesID, newQuery.ID); err != nil { log.Err(err).Msgf("error creating node queries for query %s", newQuery.Name) adminErrorResponse(w, "error creating node queries", http.StatusInternalServerError, err) return } } // Update value for expected - if err := h.Queries.SetExpected(newQuery.Name, len(targetNodesID), env.ID); err != nil { + if err := h.Queries.SetExpected(newQuery.Name, len(expectedClear), env.ID); err != nil { adminErrorResponse(w, "error setting expected", http.StatusInternalServerError, err) h.Inc(metricAdminErr) return diff --git a/api/handlers/queries.go b/api/handlers/queries.go index 75dcd03a..16ab6919 100644 --- a/api/handlers/queries.go +++ b/api/handlers/queries.go @@ -200,7 +200,7 @@ func (h *HandlersApi) QueriesRunHandler(w http.ResponseWriter, r *http.Request) if u != "" { node, err := h.Nodes.GetByUUID(u) if err != nil { - log.Warn().Msgf("error getting node %s and failed to create node query for it", u) + log.Err(err).Msgf("error getting node %s and failed to create node query for it", u) continue } expected = append(expected, node.ID) @@ -209,15 +209,13 @@ func (h *HandlersApi) QueriesRunHandler(w http.ResponseWriter, r *http.Request) targetNodesID = utils.Intersect(targetNodesID, expected) } // Create hostnames target - // Currently we are using the GetByIdentifier function and it need be more clear - // about the definition of the identifier if len(q.Hosts) > 0 { expected = []uint{} for _, hostName := range q.Hosts { if hostName != "" { node, err := h.Nodes.GetByIdentifier(hostName) if err != nil { - log.Warn().Msgf("error getting node %s and failed to create node query for it", hostName) + log.Err(err).Msgf("error getting node %s and failed to create node query for it", hostName) continue } expected = append(expected, node.ID) diff --git a/api/handlers/utils.go b/api/handlers/utils.go index 0a642e67..2c4f63cf 100644 --- a/api/handlers/utils.go +++ b/api/handlers/utils.go @@ -53,3 +53,18 @@ func checkValidPlatform(platforms []string, platform string) bool { } return false } + +// Helper to remove duplicates from []string +func removeStringDuplicates(s []string) []string { + seen := make(map[string]struct{}, len(s)) + i := 0 + for _, v := range s { + if _, ok := seen[v]; ok { + continue + } + seen[v] = struct{}{} + s[i] = v + i++ + } + return s[:i] +}