Skip to content

Commit 8edb333

Browse files
Begin trying to work on CD rtc publishing
this is going to be meaningfully tricky to respect auth policies and the complexity of the underlying data
1 parent 8c4144d commit 8edb333

File tree

2 files changed

+115
-26
lines changed

2 files changed

+115
-26
lines changed
Lines changed: 100 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,102 @@
1+
defmodule Console.Deployments.Rtc.Utils do
2+
alias Console.Repo
3+
alias Console.Schema.{Pipeline, Service, Cluster, DeploymentSettings}
4+
alias Console.Deployments.Settings
5+
6+
def audience(%Pipeline{} = pipe) do
7+
%{read_bindings: bindings} = Repo.preload(pipe, [:read_bindings])
8+
Settings.fetch()
9+
|> collect(bindings)
10+
end
11+
12+
def audience(%Service{} = service) do
13+
%{read_bindings: bindings, cluster: cluster} = Repo.preload(service, [:read_bindings, cluster: :read_bindings])
14+
audience(cluster)
15+
|> collect(bindings)
16+
end
17+
18+
def audience(%Cluster{} = cluster) do
19+
%{read_bindings: bindings} = Repo.preload(cluster, [:read_bindings])
20+
Settings.fetch()
21+
|> collect(bindings)
22+
end
23+
24+
defp collect(%DeploymentSettings{read_bindings: [_ | _] = globals}, bindings) when is_list(bindings),
25+
do: do_collect(bindings ++ globals)
26+
defp collect({_, _} = acc, bindings) when is_list(bindings), do: do_collect(bindings, acc)
27+
defp collect(_, bindings) when is_list(bindings), do: do_collect(bindings)
28+
defp collect(_, _), do: {[], []}
29+
30+
defp do_collect(bindings, acc \\ {[], []}) do
31+
{users, groups} = Enum.reduce(bindings, acc, fn
32+
%{user_id: uid}, {users, groups} when is_binary(uid) -> {[uid | users], groups}
33+
%{group_id: gid}, {users, groups} when is_binary(gid) -> {users, [gid | groups]}
34+
_, acc -> acc
35+
end)
36+
{Enum.uniq(users), Enum.uniq(groups)}
37+
end
38+
end
39+
40+
defimpl Console.GraphQl.Topic, for: Console.Schema.Service do
41+
alias Console.Deployments.Rtc.Utils
42+
def infer(item, _) do
43+
{users, groups} = Utils.audience(item)
44+
Enum.map(users, & "service:user:#{&1}")
45+
|> Enum.concat(Enum.map(groups, & "service:group:#{&1}"))
46+
|> Enum.concat(["service:admin"])
47+
|> Enum.map(& {:service_deployment_delta, &1})
48+
end
49+
end
50+
51+
defimpl Console.GraphQl.Topic, for: Console.Schema.Cluster do
52+
alias Console.Deployments.Rtc.Utils
53+
def infer(item, _) do
54+
{users, groups} = Utils.audience(item)
55+
Enum.map(users, & "cluster:user:#{&1}")
56+
|> Enum.concat(Enum.map(groups, & "cluster:group:#{&1}"))
57+
|> Enum.concat(["cluster:admin"])
58+
|> Enum.map(& {:cluster_delta, &1})
59+
end
60+
end
61+
62+
defimpl Console.GraphQl.Topic, for: Console.Schema.Pipeline do
63+
alias Console.Deployments.Rtc.Utils
64+
def infer(item, _) do
65+
{users, groups} = Utils.audience(item)
66+
Enum.map(users, & "pipeline:user:#{&1}")
67+
|> Enum.concat(Enum.map(groups, & "pipeline:group:#{&1}"))
68+
|> Enum.concat(["pipeline:admin"])
69+
|> Enum.map(& {:pipeline_delta, &1})
70+
end
71+
end
72+
173
## I need to find a way to provide authorization for this that's not a major perf drag
274

3-
# defimpl Console.PubSub.Rtc, for: [
4-
# Console.PubSub.ServiceUpdated,
5-
# Console.PubSub.ClusterUpdated,
6-
# Console.PubSub.ProviderUpdated,
7-
# Console.PubSub.GitRepositoryUpdated,
8-
# ] do
9-
# def deliver(%{item: item}), do: {item, :update}
10-
# end
11-
12-
# defimpl Console.PubSub.Rtc, for: [
13-
# Console.PubSub.ServiceCreated,
14-
# Console.PubSub.ServiceDeleted,
15-
# Console.PubSub.ClusterCreated,
16-
# Console.PubSub.ClusterDeleted,
17-
# Console.PubSub.ProviderCreated,
18-
# Console.PubSub.GitRepositoryCreated
19-
# ] do
20-
# def deliver(%{item: item}), do: {item, :create}
21-
# end
75+
defimpl Console.PubSub.Rtc, for: [
76+
Console.PubSub.ServiceUpdated,
77+
Console.PubSub.ClusterUpdated,
78+
Console.PubSub.PipelineUpdated,
79+
Console.PubSub.ServiceDeleted,
80+
Console.PubSub.ServiceComponentsUpdated,
81+
] do
82+
83+
def deliver(_), do: :ok
84+
# def deliver(%{item: item}), do: {item, :update}
85+
end
86+
87+
defimpl Console.PubSub.Rtc, for: [
88+
Console.PubSub.ServiceCreated,
89+
Console.PubSub.ClusterCreated,
90+
Console.PubSub.PipelineCreated,
91+
] do
92+
93+
def deliver(_), do: :ok
94+
# def deliver(%{item: item}), do: {item, :create}
95+
end
96+
97+
defimpl Console.PubSub.Rtc, for: [
98+
Console.PubSub.ServiceHardDeleted
99+
] do
100+
def deliver(_), do: :ok
101+
# def deliver(%{item: item}), do: {item, :delete}
102+
end

lib/console/pubsub/consumers/rtc.ex

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@ defmodule Console.PubSub.Consumers.Rtc do
66

77

88
def handle_event(event) do
9-
with {resource, delta} <- Rtc.deliver(event) do
10-
topic = Console.GraphQl.Topic.infer(resource, delta)
11-
Absinthe.Subscription.publish(
12-
ConsoleWeb.Endpoint,
13-
%{payload: resource, delta: delta},
14-
topic
15-
)
9+
case Rtc.deliver(event) do
10+
{resource, delta} ->
11+
topic = Console.GraphQl.Topic.infer(resource, delta)
12+
publish(resource, delta, topic)
13+
{resource, topics, delta} ->
14+
publish(resource, delta, topics)
15+
_ -> :ok
1616
end
1717
end
18+
19+
defp publish(resource, delta, topic) do
20+
Absinthe.Subscription.publish(
21+
ConsoleWeb.Endpoint,
22+
%{payload: resource, delta: delta},
23+
topic
24+
)
25+
end
1826
end

0 commit comments

Comments
 (0)