Skip to content

Commit

Permalink
fix cost ingest mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljguarino committed Dec 17, 2024
1 parent 510f46a commit 15281df
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 33 deletions.
1 change: 1 addition & 0 deletions assets/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8804,6 +8804,7 @@ export type ServiceUpdateAttributes = {
dryRun?: InputMaybe<Scalars['Boolean']['input']>;
git?: InputMaybe<GitRefAttributes>;
helm?: InputMaybe<HelmConfigAttributes>;
imports?: InputMaybe<Array<InputMaybe<ServiceImportAttributes>>>;
interval?: InputMaybe<Scalars['String']['input']>;
kustomize?: InputMaybe<KustomizeAttributes>;
parentId?: InputMaybe<Scalars['ID']['input']>;
Expand Down
1 change: 1 addition & 0 deletions go/client/models_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ func (r *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_
SyncConfig: attr.SyncConfig,
Dependencies: attr.Dependencies,
ParentID: attr.ParentID,
Imports: attr.Imports,
}

sha, err := utils.HashObject(updater)
Expand Down
31 changes: 17 additions & 14 deletions lib/console/cost/ingester.ex
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
defmodule Console.Cost.Ingester do
alias Console.Repo
import Console.Services.Base
import Console.Cost.Utils, only: [batch_insert: 3]
import Console.Cost.Utils, only: [batch_insert: 2]
alias Console.Schema.{Cluster, ClusterUsage, ClusterNamespaceUsage, ClusterScalingRecommendation}

def ingest(attrs, %Cluster{id: id}) do
start_transaction()
|> add_operation(:wipe_cluster, fn _ ->
ClusterUsage.for_cluster(id)
|> Repo.delete_all()
|> ok()
|> add_operation(:cluster, fn _ ->
case Repo.get_by(ClusterUsage, cluster_id: id) do
%ClusterUsage{} = usage -> usage
nil -> %ClusterUsage{cluster_id: id}
end
|> ClusterUsage.changeset(attrs[:cluster])
|> Repo.insert_or_update()
end)
|> add_operation(:wipe_namespace, fn _ ->
ClusterNamespaceUsage.for_cluster(id)
Expand All @@ -21,22 +24,17 @@ defmodule Console.Cost.Ingester do
|> Repo.delete_all()
|> ok()
end)
|> add_operation(:cluster, fn _ ->
%ClusterUsage{id: id}
|> ClusterUsage.changeset(attrs[:cluster])
|> Repo.insert()
end)
|> add_operation(:namespace, fn _ ->
Map.get(attrs, :namespaces, [])
|> Stream.map(&timestamped/1)
|> Stream.map(&cluster_timestamped(&1, id))
|> Stream.map(&Map.drop(&1, ~w(gpu_util)a))
|> batch_insert(ClusterNamespaceUsage, repo: Repo)
|> batch_insert(ClusterNamespaceUsage)
|> ok()
end)
|> add_operation(:scaling, fn _ ->
Map.get(attrs, :recommendations, [])
|> Stream.map(&timestamped/1)
|> batch_insert(ClusterScalingRecommendation, repo: Repo)
|> Stream.map(&cluster_timestamped(&1, id))
|> batch_insert(ClusterScalingRecommendation)
|> ok()
end)
|> execute()
Expand All @@ -45,4 +43,9 @@ defmodule Console.Cost.Ingester do
err -> err
end
end

defp cluster_timestamped(map, cluster_id) do
timestamped(map)
|> Map.put(:cluster_id, cluster_id)
end
end
18 changes: 9 additions & 9 deletions lib/console/deployments/pr/validation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ defmodule Console.Deployments.Pr.Validation do
defp do_validate(%Configuration{type: :int}, val) when is_integer(val), do: :ok
defp do_validate(%Configuration{type: :bool}, val) when is_boolean(val), do: :ok

defp do_validate(%Configuration{type: :enum, values: vals}, val) do
defp do_validate(%Configuration{type: :enum, name: n, values: vals}, val) do
case val in vals do
true -> :ok
false -> {:error, "#{inspect(val)} is not a member of {#{Enum.join(vals, ",")}}"}
false -> {:error, ~s(field "#{n}" with value "#{inspect(val)}" is not a member of {#{Enum.join(vals, ",")}})}
end
end

Expand All @@ -32,30 +32,30 @@ defmodule Console.Deployments.Pr.Validation do
) when is_binary(val) do
query = scope_query(scope)
case Repo.get_by(query, name: val) do
%^query{} -> {:error, "there is already a #{scope} with name #{val}"}
%^query{} -> {:error, ~s(there is already a #{scope} with name #{val})}
_ -> do_validate(put_in(conf.validation.uniq_by, nil), val)
end
end

defp do_validate(%Configuration{type: :string, validation: %Validation{json: true}}, val) when is_binary(val) do
defp do_validate(%Configuration{type: :string, name: n, validation: %Validation{json: true}}, val) when is_binary(val) do
case Jason.decode(val) do
{:ok, _} -> :ok
_ -> {:error, "value #{val} is not a json-encoded string"}
_ -> {:error, ~s(field "#{n}" with value "#{val}" is not a json-encoded string)}
end
end

defp do_validate(%Configuration{type: :string, validation: %Validation{regex: r}}, val)
defp do_validate(%Configuration{type: :string, name: n, validation: %Validation{regex: r}}, val)
when is_binary(r) and is_binary(val) do
case String.match?(val, ~r/#{r}/) do
true -> :ok
false -> {:error, "value #{val} does not match regex #{r}"}
false -> {:error, ~s(field "#{n}" with value "#{val}" does not match regex #{r})}
end
end

defp do_validate(%Configuration{type: :string}, val)
when is_binary(val) and byte_size(val) > 0, do: :ok
defp do_validate(%Configuration{type: t}, val),
do: {:error, "value #{inspect(val)} does not match type #{String.upcase(to_string(t))}"}
defp do_validate(%Configuration{type: t, name: n}, val),
do: {:error, ~s(field "#{n}" with value "#{inspect(val)}" does not match type #{String.upcase(to_string(t))})}

defp scope_query(:project), do: Project
defp scope_query(:cluster), do: Cluster
Expand Down
2 changes: 1 addition & 1 deletion lib/console/deployments/services.ex
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ defmodule Console.Deployments.Services do
def update_service(attrs, %Service{} = svc) do
start_transaction()
|> add_operation(:base, fn _ ->
svc = Repo.preload(svc, [:context_bindings, :dependencies, :read_bindings, :write_bindings])
svc = Repo.preload(svc, [:context_bindings, :dependencies, :read_bindings, :write_bindings, :imports])
attrs = Map.put(attrs, :status, :stale)
svc
|> Service.changeset(stabilize_deps(attrs, svc))
Expand Down
1 change: 1 addition & 0 deletions lib/console/graphql/deployments/service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ defmodule Console.GraphQl.Deployments.Service do
field :read_bindings, list_of(:policy_binding_attributes)
field :write_bindings, list_of(:policy_binding_attributes)
field :context_bindings, list_of(:context_binding_attributes)
field :imports, list_of(:service_import_attributes)
end

input_object :service_clone_attributes do
Expand Down
2 changes: 2 additions & 0 deletions schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3818,6 +3818,8 @@ input ServiceUpdateAttributes {
writeBindings: [PolicyBindingAttributes]

contextBindings: [ContextBindingAttributes]

imports: [ServiceImportAttributes]
}

input ServiceCloneAttributes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,20 @@ defmodule Console.GraphQl.Deployments.ClusterMutationsTest do
}
""", %{"costs" => ingest}, %{cluster: cluster})

assert Console.Repo.aggregate(Console.Schema.ClusterUsage, :count, :id) == 1
assert Console.Repo.aggregate(Console.Schema.ClusterNamespaceUsage, :count, :id) == 1
assert Console.Repo.aggregate(Console.Schema.ClusterScalingRecommendation, :count, :id) == 1
{:ok, %{data: %{"ingestClusterCost" => true}}} = run_query("""
mutation Ingest($costs: CostIngestAttributes!) {
ingestClusterCost(costs: $costs)
}
""", %{"costs" => ingest}, %{cluster: cluster})

[usage] = Console.Repo.all(Console.Schema.ClusterUsage)
assert usage.cluster_id == cluster.id

[ns] = Console.Repo.all(Console.Schema.ClusterNamespaceUsage)
assert ns.cluster_id == cluster.id

[sr] = Console.Repo.all(Console.Schema.ClusterScalingRecommendation)
assert sr.cluster_id == cluster.id
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -405,16 +405,13 @@ defmodule Console.GraphQl.Deployments.ClusterQueriesTest do
query Runtime($id: ID!) {
runtimeService(id: $id) {
id
addon {
versions { version kube }
readme
}
addon { versions { version kube } }
}
}
""", %{"id" => runtime.id}, %{current_user: user})

assert rs["id"] == runtime.id
assert rs["addon"]["readme"]
# assert rs["addon"]["readme"]
end

test "users w/o cluster read cannot fetch a runtime service by id" do
Expand All @@ -428,7 +425,6 @@ defmodule Console.GraphQl.Deployments.ClusterQueriesTest do
id
addon {
versions { version kube }
readme
}
}
}
Expand Down

0 comments on commit 15281df

Please sign in to comment.