Skip to content

Commit a8d4374

Browse files
Need to b64 decode cockroach config secret (#1336)
1 parent 14c08fb commit a8d4374

21 files changed

+180
-128
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ test-certs:
6464
cockroach cert create-client root --certs-dir test-certs --ca-key test-certs/ca.key && \
6565
cockroach cert list --certs-dir test-certs
6666

67-
testup: test-certs ## sets up dependent services for test
68-
docker compose up -d
67+
testup: ## sets up dependent services for test
68+
docker compose up -d --remove-orphans
6969

7070
testdown: ## tear down test dependencies
7171
docker compose down

apps/core/lib/core/clients/console.ex

+27-3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ defmodule Core.Clients.Console do
4141
}
4242
"""
4343

44+
@stack_q """
45+
query Stack($id: ID!) {
46+
infrastructureStack(id: $id) {
47+
id
48+
output {
49+
name
50+
value
51+
}
52+
}
53+
}
54+
"""
55+
4456
def new(url, token) do
4557
Req.new(base_url: with_gql(url), auth: "Token #{token}")
4658
|> AbsintheClient.attach()
@@ -49,7 +61,8 @@ defmodule Core.Clients.Console do
4961
def clusters(client) do
5062
Req.post(client, graphql: @clusters_q)
5163
|> case do
52-
{:ok, %Req.Response{body: %{"clusters" => %{"edges" => edges}}}} -> {:ok, Enum.map(edges, & &1["node"])}
64+
{:ok, %Req.Response{body: %{"data" => %{"clusters" => %{"edges" => edges}}}}} ->
65+
{:ok, Enum.map(edges, & &1["node"])}
5366
res ->
5467
Logger.warn "Failed to fetch clusters: #{inspect(res)}"
5568
{:error, "could not fetch clusters"}
@@ -59,7 +72,7 @@ defmodule Core.Clients.Console do
5972
def repo(client, url) do
6073
Req.post(client, graphql: {@repo_q, %{url: url}})
6174
|> case do
62-
{:ok, %Req.Response{body: %{"gitRepository" => %{"id" => id}}}} -> {:ok, id}
75+
{:ok, %Req.Response{body: %{"data" => %{"gitRepository" => %{"id" => id}}}}} -> {:ok, id}
6376
res ->
6477
Logger.warn "Failed to fetch clusters: #{inspect(res)}"
6578
{:error, "could not fetch repo"}
@@ -81,7 +94,18 @@ defmodule Core.Clients.Console do
8194
|> service_resp("deleteServiceDeployment")
8295
end
8396

84-
defp service_resp({:ok, %Req.Response{status: 200, body: body}}, field) do
97+
def stack(client, id) do
98+
Req.post(client, graphql: {@stack_q, %{id: id}})
99+
|> case do
100+
{:ok, %Req.Response{body: %{"data" => %{"infrastructureStack" => stack}}}} ->
101+
{:ok, stack}
102+
res ->
103+
Logger.warn "Failed to fetch stack: #{inspect(res)}"
104+
{:error, "could not fetch stack"}
105+
end
106+
end
107+
108+
defp service_resp({:ok, %Req.Response{status: 200, body: %{"data" => body}}}, field) do
85109
case body[field] do
86110
%{"id" => id} -> {:ok, id}
87111
err ->

apps/core/lib/core/schema/console_instance.ex

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Core.Schema.ConsoleInstance do
22
use Piazza.Ecto.Schema
33
alias Piazza.Ecto.EncryptedString
4-
alias Core.Schema.{CockroachCluster, CloudCluster, User}
4+
alias Core.Schema.{PostgresCluster, CloudCluster, User}
55

66
defenum Size, small: 0, medium: 1, large: 2
77
defenum Status,
@@ -41,6 +41,7 @@ defmodule Core.Schema.ConsoleInstance do
4141
field :dbpassword, EncryptedString
4242
field :subdomain, :string
4343
field :jwt_secret, EncryptedString
44+
field :erlang_secret, EncryptedString
4445
field :owner_name, :string
4546
field :owner_email, :string
4647
field :admin_password, EncryptedString
@@ -54,7 +55,7 @@ defmodule Core.Schema.ConsoleInstance do
5455
field :kas_redis, EncryptedString
5556
end
5657

57-
belongs_to :cockroach, CockroachCluster
58+
belongs_to :postgres, PostgresCluster
5859
belongs_to :cluster, CloudCluster
5960
belongs_to :owner, User
6061

@@ -91,7 +92,7 @@ defmodule Core.Schema.ConsoleInstance do
9192

9293
def regions(), do: @region_map
9394

94-
@valid ~w(name cloud size region status subdomain url external_id cockroach_id cluster_id owner_id)a
95+
@valid ~w(name cloud size region status subdomain url external_id postgres_id cluster_id owner_id)a
9596

9697
def changeset(model, attrs \\ %{}) do
9798
model
@@ -117,7 +118,7 @@ defmodule Core.Schema.ConsoleInstance do
117118
end
118119

119120
@conf_valid ~w(
120-
database dbuser dbpassword
121+
database dbuser dbpassword erlang_secret
121122
subdomain jwt_secret owner_name owner_email admin_password aes_key
122123
encryption_key client_id client_secret plural_token
123124
kas_api kas_private kas_redis

apps/core/lib/core/schema/cockroach_cluster.ex renamed to apps/core/lib/core/schema/postgres_cluster.ex

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
defmodule Core.Schema.CockroachCluster do
1+
defmodule Core.Schema.PostgresCluster do
22
use Piazza.Ecto.Schema
33
alias Piazza.Ecto.EncryptedString
44
alias Core.Schema.CloudCluster
55

66
@saturation 1000
77

8-
schema "cockroach_clusters" do
8+
schema "postgres_clusters" do
99
field :name, :string
1010
field :cloud, CloudCluster.Cloud
1111
field :region, :string
1212
field :url, EncryptedString
13+
field :host, :string
1314
field :certificate, :string
1415
field :endpoints, :map
1516
field :count, :integer, default: 0
@@ -27,8 +28,8 @@ defmodule Core.Schema.CockroachCluster do
2728

2829
def changeset(model, attrs \\ %{}) do
2930
model
30-
|> cast(attrs, ~w(name cloud region url certificate endpoints)a)
31+
|> cast(attrs, ~w(name cloud region url host certificate endpoints)a)
3132
|> unique_constraint(:name)
32-
|> validate_required(~w(name cloud region url certificate endpoints)a)
33+
|> validate_required(~w(name cloud url host)a)
3334
end
3435
end

apps/core/lib/core/services/cloud.ex

+22-21
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ defmodule Core.Services.Cloud do
44
alias Core.Repo
55
alias Core.PubSub
66
alias Core.Services.{Accounts, Users, Repositories, Shell}
7-
alias Core.Schema.{CloudCluster, CockroachCluster, ConsoleInstance, User, OIDCProvider}
7+
alias Core.Schema.{CloudCluster, PostgresCluster, ConsoleInstance, User, OIDCProvider}
88

99
@type error :: {:error, term}
1010
@type console_resp :: {:ok, ConsoleInstance.t} | error
1111
@type cluster_resp :: {:ok, CloudCluster.t} | error
12-
@type cockroach_resp :: {:ok, CockroachCluster.t} | error
12+
@type postgres_resp :: {:ok, PostgresCluster.t} | error
1313

1414
def get_instance!(id), do: Repo.get!(ConsoleInstance, id)
1515

@@ -23,13 +23,13 @@ defmodule Core.Services.Cloud do
2323
|> Repo.insert_or_update()
2424
end
2525

26-
@spec upsert_cockroach(map, binary) :: cockroach_resp
27-
def upsert_cockroach(attrs, name) do
28-
case Repo.get_by(CockroachCluster, name: name) do
29-
%CockroachCluster{} = cluster -> cluster
30-
nil -> %CockroachCluster{name: name}
26+
@spec upsert_postgres(map, binary) :: postgres_resp
27+
def upsert_postgres(attrs, name) do
28+
case Repo.get_by(PostgresCluster, name: name) do
29+
%PostgresCluster{} = cluster -> cluster
30+
nil -> %PostgresCluster{name: name}
3131
end
32-
|> CockroachCluster.changeset(attrs)
32+
|> PostgresCluster.changeset(attrs)
3333
|> Repo.insert_or_update()
3434
end
3535

@@ -41,7 +41,7 @@ defmodule Core.Services.Cloud do
4141
start_transaction()
4242
|> add_operation(:auth, fn _ -> allow(%ConsoleInstance{}, user, :create) end)
4343
|> add_operation(:cluster, fn _ -> select_cluster(attrs[:cloud], attrs[:region]) end)
44-
|> add_operation(:cockroach, fn _ -> select_roach(attrs[:cloud]) end)
44+
|> add_operation(:postgres, fn _ -> select_roach(attrs[:cloud]) end)
4545
|> add_operation(:sa, fn _ ->
4646
Accounts.create_service_account(%{name: "#{name}-cloud-sa", email: "#{name}-cloud-sa@srv.plural.sh"}, user)
4747
end)
@@ -58,11 +58,11 @@ defmodule Core.Services.Cloud do
5858
Repositories.upsert_oidc_provider(%{
5959
auth_method: :post,
6060
bindings: Shell.oidc_bindings(inst.oidc_provider, user),
61-
redirect_uris: Shell.merge_uris(["https://console.#{name}.cloud.plural.sh/oauth/callback"], inst.oidc_provider)
61+
redirect_uris: Shell.merge_uris(["https://console-#{name}.cloud.plural.sh/oauth/callback"], inst.oidc_provider)
6262
}, inst.id, sa)
6363
end)
64-
|> add_operation(:instance, fn %{oidc: oidc, token: token, cluster: cluster, cockroach: roach, sa: sa} ->
65-
%ConsoleInstance{status: :pending, cluster_id: cluster.id, cockroach_id: roach.id, owner_id: sa.id}
64+
|> add_operation(:instance, fn %{oidc: oidc, token: token, cluster: cluster, postgres: roach, sa: sa} ->
65+
%ConsoleInstance{status: :pending, cluster_id: cluster.id, postgres_id: roach.id, owner_id: sa.id}
6666
|> ConsoleInstance.changeset(add_configuration(attrs, name, token.token, oidc, user))
6767
|> Repo.insert()
6868
end)
@@ -135,24 +135,25 @@ defmodule Core.Services.Cloud do
135135
end
136136

137137
defp add_configuration(attrs, name, token, %OIDCProvider{} = oidc, %User{} = user) do
138-
Map.merge(attrs, %{subdomain: "#{name}.cloud.plural.sh", url: "console.#{name}.cloud.plural.sh"})
138+
Map.merge(attrs, %{subdomain: "#{name}.cloud.plural.sh", url: "console-#{name}.cloud.plural.sh"})
139139
|> Map.put(:configuration, %{
140140
aes_key: aes_key(),
141141
encryption_key: encryption_key(),
142142
database: "#{name}_cloud",
143143
dbuser: "#{name}_user",
144-
dbpassword: Core.random_alphanum(30),
144+
dbpassword: Core.random_alphanum(32),
145145
subdomain: "#{name}.cloud.plural.sh",
146-
jwt_secret: Core.random_alphanum(30),
146+
jwt_secret: Core.random_alphanum(32) |> Base.encode64(),
147147
owner_name: user.name,
148148
owner_email: user.email,
149-
admin_password: Core.random_alphanum(30),
149+
admin_password: Core.random_alphanum(32) |> Base.encode64(),
150+
erlang_secret: Core.random_alphanum(32) |> Base.encode64(),
150151
client_id: oidc.client_id,
151152
client_secret: oidc.client_secret,
152153
plural_token: token,
153-
kas_api: Core.random_alphanum(30),
154-
kas_private: Core.random_alphanum(30),
155-
kas_redis: Core.random_alphanum(30)
154+
kas_api: Core.random_alphanum(64) |> Base.encode64(),
155+
kas_private: Core.random_alphanum(64) |> Base.encode64(),
156+
kas_redis: Core.random_alphanum(64) |> Base.encode64(),
156157
})
157158
end
158159

@@ -165,8 +166,8 @@ defmodule Core.Services.Cloud do
165166
end
166167

167168
defp select_roach(cloud) do
168-
CockroachCluster.for_cloud(cloud)
169-
|> CockroachCluster.unsaturated()
169+
PostgresCluster.for_cloud(cloud)
170+
|> PostgresCluster.unsaturated()
170171
|> Repo.all()
171172
|> random_choice("Could not place in #{cloud}")
172173
end

apps/core/lib/core/services/cloud/configuration.ex

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
defmodule Core.Services.Cloud.Configuration do
2-
alias Core.Schema.{ConsoleInstance, CockroachCluster}
2+
alias Core.Schema.{ConsoleInstance, PostgresCluster}
33

44
def build(%ConsoleInstance{configuration: conf, size: size} = inst) do
55
Map.take(conf, ~w(
@@ -16,23 +16,24 @@ defmodule Core.Services.Cloud.Configuration do
1616
kas_api
1717
kas_private
1818
kas_redis
19+
erlang_secret
1920
)a)
2021
|> Map.merge(%{
2122
postgres_url: build_pg_url(inst),
23+
cloud: "#{inst.cloud}",
24+
cluster_name: inst.name,
2225
size: "#{size}",
23-
postgres_certificate: certificate(inst)
2426
})
2527
|> Map.put(:size, "#{size}")
26-
|> Enum.map(fn {k, v} -> %{name: Macro.camelize("#{k}"), value: v} end)
28+
|> Enum.map(fn {k, v} -> %{name: k, value: v} end)
2729
end
2830

29-
defp certificate(%ConsoleInstance{cockroach: %CockroachCluster{certificate: cert}}), do: cert
31+
# defp certificate(%ConsoleInstance{postgres: %PostgresCluster{certificate: cert}}), do: cert
3032

3133
defp build_pg_url(%ConsoleInstance{
3234
configuration: %{dbuser: u, dbpassword: p, database: database},
33-
region: region,
34-
cockroach: %CockroachCluster{endpoints: endpoints}
35+
postgres: %PostgresCluster{host: host}
3536
}) do
36-
"postgresql://#{u}:#{p}@#{endpoints[region]}/#{database}"
37+
"postgresql://#{u}:#{p}@#{host}/#{database}"
3738
end
3839
end

apps/core/lib/core/services/cloud/poller.ex

+22-27
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ defmodule Core.Services.Cloud.Poller do
22
use GenServer
33
alias Core.Clients.Console
44
alias Core.Services.Cloud
5-
alias Kazan.Apis.Core.V1, as: CoreV1
65
require Logger
76

8-
@poll :timer.minutes(5)
7+
@poll :timer.minutes(2)
98

109
defmodule State, do: defstruct [:client, :repo]
1110

@@ -15,16 +14,16 @@ defmodule Core.Services.Cloud.Poller do
1514

1615
def init(_) do
1716
:timer.send_interval(@poll, :clusters)
18-
:timer.send_interval(@poll, :roaches)
17+
:timer.send_interval(@poll, :pgs)
1918
send self(), :repo
2019
{:ok, %State{client: Console.new(Core.conf(:console_url), Core.conf(:console_token))}}
2120
end
2221

2322
def repository(), do: GenServer.call(__MODULE__, :repo)
2423

25-
def handle_call(:repo, %{repo: id} = state) when is_binary(id),
24+
def handle_call(:repo, _, %{repo: id} = state) when is_binary(id),
2625
do: {:reply, {:ok, id}, state}
27-
def handle_call(:repo, state), do: {:reply, {:error, "repo not pulled"}, state}
26+
def handle_call(:repo, _, state), do: {:reply, {:error, "repo not pulled"}, state}
2827

2928
def handle_info(:repo, %{client: client} = state) do
3029
case Console.repo(client, Core.conf(:mgmt_repo)) do
@@ -43,12 +42,13 @@ defmodule Core.Services.Cloud.Poller do
4342
{:noreply, state}
4443
end
4544

46-
def handle_info(:roaches, state) do
47-
case read_secret() do
48-
{:ok, roaches} ->
49-
Enum.each(roaches, &upsert_roach/1)
50-
err ->
51-
Logger.warn "failed to fetch available cockroach clusters: #{inspect(err)}"
45+
def handle_info(:pgs, %{client: client} = state) do
46+
with {:ok, stack} <- Console.stack(client, Core.conf(:stack_id)),
47+
%{"value" => v} <- Enum.find(stack["output"], & &1["name"] == "clusters"),
48+
{:ok, pgs} <- Jason.decode(v) do
49+
Enum.each(pgs, fn {k, v} -> upsert_pg(k, v) end)
50+
else
51+
err -> Logger.warn "failed to fetch cluster info: #{inspect(err)}"
5252
end
5353
{:noreply, state}
5454
end
@@ -61,29 +61,24 @@ defmodule Core.Services.Cloud.Poller do
6161
cloud: to_cloud(distro),
6262
region: meta["region"]
6363
}, name)
64+
|> log_err("failed to insert cloud cluster")
6465
end
6566

66-
defp upsert_roach(%{"name" => name} = roach) do
67-
Cloud.upsert_cockroach(%{
68-
cloud: roach["cloud"],
69-
url: roach["url"],
70-
certificate: roach["certificate"],
71-
endpoints: roach["endpoints"]
67+
defp upsert_pg(name, pg) do
68+
Cloud.upsert_postgres(%{
69+
cloud: pg["cloud"],
70+
url: pg["url"],
71+
# certificate: pg["certificate"],
72+
host: pg["host"]
7273
}, name)
73-
end
74-
75-
defp read_secret() do
76-
CoreV1.read_namespaced_secret!("plural", "plrl-cloud-config")
77-
|> Kazan.run()
78-
|> case do
79-
{:ok, %CoreV1.Secret{data: %{"cockroaches" => roaches}}} ->
80-
Jason.decode(roaches)
81-
_ -> {:error, "could not find secret"}
82-
end
74+
|> log_err("failed to insert postgres cluster")
8375
end
8476

8577
defp to_cloud("EKS"), do: :aws
8678
defp to_cloud("GKE"), do: :gcp
8779
defp to_cloud("AKS"), do: :azure
8880
defp to_cloud(_), do: :aws
81+
82+
defp log_err({:error, _} = err, msg), do: "#{msg}: #{inspect(err)}"
83+
defp log_err(pass, _), do: pass
8984
end

0 commit comments

Comments
 (0)