Skip to content

Commit

Permalink
fix service queries
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljguarino committed Jan 11, 2025
1 parent 361d4de commit 2ce6e40
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 22 deletions.
36 changes: 18 additions & 18 deletions lib/console/logs/provider/elastic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Console.Logs.Provider.Elastic do
case HTTPoison.post("#{host}/#{index}/_search", Jason.encode!(query), headers(conn)) do
{:ok, %HTTPoison.Response{body: body, status_code: 200}} ->
with {:ok, resp} <- Jason.decode(body),
do: Snap.SearchResponse.new(resp)
do: {:ok, Snap.SearchResponse.new(resp)}
{:ok, %HTTPoison.Response{body: body}} -> {:error, body}
err -> err
end
Expand All @@ -55,42 +55,42 @@ defmodule Console.Logs.Provider.Elastic do
end

defp add_terms(query, %Query{resource: %Cluster{} = cluster}),
do: Map.put(query, :term, term(cluster))
defp add_terms(query, %Query{resource: %Service{cluster: %Cluster{} = cluster}} = svc),
do: Map.put(query, :term, term(cluster) |> term(svc))
do: put_in(query[:bool][:filter], [%{term: %{"cluster.handle.keyword" => cluster.handle}}])
defp add_terms(query, %Query{resource: %Service{cluster: %Cluster{} = cluster} = svc}) do
put_in(query[:bool][:filter], [
%{term: %{"kubernetes.namespace.keyword" => svc.namespace}},
%{term: %{"cluster.handle.keyword" => cluster.handle}}
])
end
defp add_terms(query, _), do: query

defp add_range(q, %Query{time: %Time{after: aft, before: bef}}) when not is_nil(aft) and not is_nil(bef),
do: Map.put(q, :range, %{"@timestamp": %{gte: aft, lte: bef}})
do: add_filter(q, %{range: %{"@timestamp": %{gte: aft, lte: bef}}})
defp add_range(q, %Query{time: %Time{after: aft, before: nil, duration: dur}}) when not is_nil(aft),
do: Map.put(q, :range, %{"@timestamp": maybe_dur(:gte, aft, dur)})
do: add_filter(q, %{range: %{"@timestamp": maybe_dur(:gte, aft, dur)}})
defp add_range(q, %Query{time: %Time{after: nil, before: bef, duration: dur}}) when not is_nil(bef),
do: Map.put(q, :range, %{"@timestamp": maybe_dur(:lte, bef, dur)})
do: add_filter(q, %{range: %{"@timestamp": maybe_dur(:lte, bef, dur)}})
defp add_range(q, _), do: q

defp add_facets(q, %Query{facets: [_ | _] = facets}) do
term = Map.get(q, :term, %{})
facets = Enum.reduce(facets, term, fn %{key: k, value: v}, acc ->
Map.put(acc, k, %{value: v})
Enum.reduce(facets, q, fn %{key: k, value: v}, acc ->
add_filter(q, %{term: %{"#{k}.keyword" => v}})
end)

Map.put(q, :term, facets)
end
defp add_facets(q, _), do: q

defp term(q \\ %{}, resource)
defp term(q, %Cluster{handle: handle}), do: Map.put(q, :"cluster.name", %{value: handle})
defp term(q, %Service{namespace: namespace}), do: Map.put(q, :"kubernetes.namespace", %{value: namespace})

defp facets(resp) do
Map.take(resp, ~w(kubernetes cloud container cluster))
|> Line.flat_map()
|> Line.facets()
end

defp add_filter(%{bool: %{filter: fs}} = q, range) when is_list(fs), do: put_in(q[:bool][:filter], [range | fs])
defp add_filter(q, range), do: put_in(q[:bool][:filter], [range])

defp maybe_query(q) when is_binary(q) and byte_size(q) > 0,
do: %{query_string: %{query: q, default_field: "message"}}
defp maybe_query(_), do: %{}
do: %{bool: %{must: %{match: %{message: q}}}}
defp maybe_query(_), do: %{bool: %{}}

defp maybe_dur(dir, ts, duration) when is_binary(duration) do
opp = opposite(dir)
Expand Down
10 changes: 6 additions & 4 deletions lib/console/logs/query.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule Console.Logs.Query do
alias Console.Repo
alias Console.Logs.Time
alias Console.Schema.{User, Project, Cluster, Service}
alias Console.Deployments.Policies
Expand All @@ -24,23 +25,24 @@ defmodule Console.Logs.Query do
def limit(%__MODULE__{limit: l}) when is_integer(l), do: l
def limit(_), do: @default_limit

def preload(%__MODULE__{resource: %Service{} = svc} = query),
do: %{query | resource: Repo.preload(svc, [:cluster])}
def preload(q), do: q

def accessible(%__MODULE__{project_id: project_id} = q, %User{} = user) when is_binary(project_id),
do: check_access(Project, project_id, user, q)

def accessible(%__MODULE__{cluster_id: id} = q, %User{} = user) when is_binary(id),
do: check_access(Cluster, id, user, q)

def accessible(%__MODULE__{service_id: id} = q, %User{} = user) when is_binary(id),
do: check_access(Service, id, user, q)

def accessible(_, _), do: {:error, "forbidden"}

defp check_access(model, id, user, query) do
Console.Repo.get!(model, id)
|> Policies.allow(user, :read)
|> case do
{:ok, resource} -> {:ok, %{query | resource: resource}}
{:ok, resource} ->
{:ok, preload(%{query | resource: resource})}
err -> err
end
end
Expand Down

0 comments on commit 2ce6e40

Please sign in to comment.