Skip to content

Commit

Permalink
Edit AstartePairing :use keyspace name instead of realm in queries
Browse files Browse the repository at this point in the history
Currently Astarte instances are not allowd to share the same database due to a conflict in namespaces
resolution (eg. two realms with same name in different astarte instances now share the same kespace,
that's not good)

This commit introduce univoque mapping between the pair <Astarte instance id, realm name>
and keyspace name (see also  astarte-platform/astarte_core#105), this way even
with the same name, realms do not share the same keyspace.
Also, the env var `ASTARTE_INSTANCE_ID`, defaulting to `""` has been added to
maintain backward compatibility.

Trivially change all queries to the database to reflect this change, both in `lib` and `tests`.

Signed-off-by: Eddy Babetto <eddy.babetto@secomind.com>
  • Loading branch information
eddbbt committed Apr 24, 2024
1 parent bc5ed1b commit 55f242b
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 32 deletions.
2 changes: 2 additions & 0 deletions apps/astarte_pairing/config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ config :astarte_pairing,
:cfssl_url,
System.get_env("CFSSL_API_URL") || "http://ispirata-docker-alpine-cfssl-autotest:8080"

config :astarte_pairing, :astarte_instance_id, "test"

config :bcrypt_elixir,
log_rounds: 4

Expand Down
3 changes: 3 additions & 0 deletions apps/astarte_pairing/lib/astarte_pairing/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,7 @@ defmodule Astarte.Pairing.Config do

defdelegate xandra_options!, to: DataAccessConfig
defdelegate cqex_options!, to: DataAccessConfig

defdelegate astarte_instance_id!, to: DataAccessConfig
defdelegate astarte_instance_id, to: DataAccessConfig
end
22 changes: 16 additions & 6 deletions apps/astarte_pairing/lib/astarte_pairing/engine.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ defmodule Astarte.Pairing.Engine do
alias Astarte.Pairing.CredentialsSecret
alias Astarte.Pairing.Queries
alias CQEx.Client
alias Astarte.Core.CQLUtils

require Logger

Expand Down Expand Up @@ -56,9 +57,11 @@ defmodule Astarte.Pairing.Engine do
end

def get_agent_public_key_pems(realm) do
keyspace = CQLUtils.realm_name_to_keyspace_name(realm, Config.astarte_instance_id!())

cqex_options =
Config.cqex_options!()
|> Keyword.put(:keyspace, realm)
|> Keyword.put(:keyspace, keyspace)

with {:ok, client} <-
Client.new(
Expand Down Expand Up @@ -89,10 +92,11 @@ defmodule Astarte.Pairing.Engine do
)

:telemetry.execute([:astarte, :pairing, :get_credentials], %{}, %{realm: realm})
keyspace_name = CQLUtils.realm_name_to_keyspace_name(realm, Config.astarte_instance_id!())

cqex_options =
Config.cqex_options!()
|> Keyword.put(:keyspace, realm)
|> Keyword.put(:keyspace, keyspace_name)

with {:ok, device_id} <- Device.decode_device_id(hardware_id, allow_extended_id: true),
{:ok, ip_tuple} <- parse_ip(device_ip),
Expand Down Expand Up @@ -152,10 +156,11 @@ defmodule Astarte.Pairing.Engine do

def get_info(realm, hardware_id, credentials_secret) do
Logger.debug("get_info request for device #{inspect(hardware_id)} in realm #{inspect(realm)}")
keyspace_name = CQLUtils.realm_name_to_keyspace_name(realm, Config.astarte_instance_id!())

cqex_options =
Config.cqex_options!()
|> Keyword.put(:keyspace, realm)
|> Keyword.put(:keyspace, keyspace_name)

with {:ok, device_id} <- Device.decode_device_id(hardware_id, allow_extended_id: true),
{:ok, client} <-
Expand Down Expand Up @@ -192,10 +197,11 @@ defmodule Astarte.Pairing.Engine do
)

:telemetry.execute([:astarte, :pairing, :register_new_device], %{}, %{realm: realm})
keyspace_name = CQLUtils.realm_name_to_keyspace_name(realm, Config.astarte_instance_id!())

cqex_options =
Config.cqex_options!()
|> Keyword.put(:keyspace, realm)
|> Keyword.put(:keyspace, keyspace_name)

with :ok <- verify_can_register_device(realm),
{:ok, device_id} <- Device.decode_device_id(hardware_id, allow_extended_id: true),
Expand Down Expand Up @@ -240,9 +246,11 @@ defmodule Astarte.Pairing.Engine do
"in realm #{inspect(realm)}"
)

keyspace_name = CQLUtils.realm_name_to_keyspace_name(realm, Config.astarte_instance_id!())

cqex_options =
Config.cqex_options!()
|> Keyword.put(:keyspace, realm)
|> Keyword.put(:keyspace, keyspace_name)

with {:ok, device_id} <- Device.decode_device_id(encoded_device_id),
{:ok, client} <-
Expand All @@ -266,9 +274,11 @@ defmodule Astarte.Pairing.Engine do
"verify_credentials request for device #{inspect(hardware_id)} in realm #{inspect(realm)}"
)

keyspace_name = CQLUtils.realm_name_to_keyspace_name(realm, Config.astarte_instance_id!())

cqex_options =
Config.cqex_options!()
|> Keyword.put(:keyspace, realm)
|> Keyword.put(:keyspace, keyspace_name)

with {:ok, device_id} <- Device.decode_device_id(hardware_id, allow_extended_id: true),
{:ok, client} <-
Expand Down
14 changes: 9 additions & 5 deletions apps/astarte_pairing/lib/astarte_pairing/queries.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ defmodule Astarte.Pairing.Queries do

alias CQEx.Query
alias CQEx.Result

alias Astarte.Core.CQLUtils
alias Astarte.Pairing.Config
require Logger

@protocol_revision 1
Expand Down Expand Up @@ -316,7 +317,7 @@ defmodule Astarte.Pairing.Queries do
def check_astarte_health(consistency) do
query = """
SELECT COUNT(*)
FROM astarte.realms
FROM #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())}.realms
"""

with {:ok, %Xandra.Page{} = page} <-
Expand Down Expand Up @@ -353,7 +354,7 @@ defmodule Astarte.Pairing.Queries do
defp do_fetch_device_registration_limit(conn, realm_name) do
query = """
SELECT device_registration_limit
FROM astarte.realms
FROM #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())}.realms
WHERE realm_name = :realm_name
"""

Expand Down Expand Up @@ -394,14 +395,17 @@ defmodule Astarte.Pairing.Queries do

defp do_fetch_registered_devices_count(conn, realm_name) do
# TODO move away from interpolation like this once NoaccOS' PR is merged
keyspace_name =
CQLUtils.realm_name_to_keyspace_name(realm_name, Config.astarte_instance_id!())

query = """
SELECT COUNT(*)
FROM #{realm_name}.devices
FROM #{keyspace_name}.devices
"""

with {:ok, prepared} <- Xandra.prepare(conn, query),
{:ok, page} <-
Xandra.execute(conn, prepared, %{"realm_name" => realm_name}, consistency: :one) do
Xandra.execute(conn, prepared, %{}, consistency: :one) do
[%{"count" => value}] = Enum.to_list(page)
{:ok, value}
else
Expand Down
8 changes: 4 additions & 4 deletions apps/astarte_pairing/mix.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
%{
"amqp": {:hex, :amqp, "3.3.0", "056d9f4bac96c3ab5a904b321e70e78b91ba594766a1fc2f32afd9c016d9f43b", [:mix], [{:amqp_client, "~> 3.9", [hex: :amqp_client, repo: "hexpm", optional: false]}], "hexpm", "8d3ae139d2646c630d674a1b8d68c7f85134f9e8b2a1c3dd5621616994b10a8b"},
"amqp_client": {:hex, :amqp_client, "3.12.10", "dcc0d5d0037fa2b486c6eb8b52695503765b96f919e38ca864a7b300b829742d", [:make, :rebar3], [{:credentials_obfuscation, "3.4.0", [hex: :credentials_obfuscation, repo: "hexpm", optional: false]}, {:rabbit_common, "3.12.10", [hex: :rabbit_common, repo: "hexpm", optional: false]}], "hexpm", "16a23959899a82d9c2534ed1dcf1fa281d3b660fb7f78426b880647f0a53731f"},
"astarte_core": {:git, "https://github.com/astarte-platform/astarte_core.git", "685ca10c7a07cc9806f2c6fc7ec2ed1b4d23cbec", []},
"astarte_data_access": {:git, "https://github.com/astarte-platform/astarte_data_access.git", "45d4d20ae662751f47f4b8f2f9d5e302d5485ea9", []},
"astarte_rpc": {:git, "https://github.com/astarte-platform/astarte_rpc.git", "5adf50beffa0bac18d99ebe378bc677c7669a767", []},
"astarte_core": {:git, "https://github.com/astarte-platform/astarte_core.git", "dc964b7d9b3a3a4e20127b763705d9e53bd88890", []},
"astarte_data_access": {:git, "https://github.com/astarte-platform/astarte_data_access.git", "6efd21dcab8c16affa1888cc5e9218ecf7df67f2", []},
"astarte_rpc": {:git, "https://github.com/astarte-platform/astarte_rpc.git", "c0d77760fb12256a23a2d00e1a119496a089fa9d", []},
"bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.0", "6cb662d5c1b0a8858801cf20997bd006e7016aa8c52959c9ef80e0f34fb60b7a", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "2c81d61d4f6ed0e5cf7bf27a9109b791ff216a1034b3d541327484f46dd43769"},
"castore": {:hex, :castore, "0.1.16", "2675f717adc700475345c5512c381ef9273eb5df26bdd3f8c13e2636cf4cc175", [:mix], [], "hexpm", "28ed2c43d83b5c25d35c51bc0abf229ac51359c170cba76171a462ced2e4b651"},
"castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"cfxxl": {:git, "https://github.com/ispirata/cfxxl.git", "98dc50b1cfe5a682b051b38b83cebc644bc08488", []},
"comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"},
Expand Down
11 changes: 9 additions & 2 deletions apps/astarte_pairing/test/astarte_pairing/engine_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ defmodule Astarte.Pairing.EngineTest do

alias Astarte.Core.Device
alias Astarte.Pairing.Config
alias Astarte.Core.CQLUtils
alias Astarte.Pairing.CredentialsSecret
alias Astarte.Pairing.DatabaseTestHelper
alias Astarte.Pairing.Engine
Expand Down Expand Up @@ -371,7 +372,10 @@ defmodule Astarte.Pairing.EngineTest do

db_client =
Config.cassandra_node!()
|> CQEx.Client.new!(keyspace: @test_realm)
|> CQEx.Client.new!(
keyspace:
CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

{:ok, device} = Queries.select_device_for_credentials_request(db_client, device_id)

Expand All @@ -387,7 +391,10 @@ defmodule Astarte.Pairing.EngineTest do

db_client =
Config.cassandra_node!()
|> CQEx.Client.new!(keyspace: @test_realm)
|> CQEx.Client.new!(
keyspace:
CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

{:ok, no_credentials_requested_device} =
Queries.select_device_for_credentials_request(db_client, device_id)
Expand Down
41 changes: 26 additions & 15 deletions apps/astarte_pairing/test/support/database_test_helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

defmodule Astarte.Pairing.DatabaseTestHelper do
alias Astarte.Core.Device
alias Astarte.Core.CQLUtils
alias Astarte.Pairing.Config
alias Astarte.Pairing.TestHelper
alias Astarte.Pairing.CredentialsSecret
Expand All @@ -27,21 +28,21 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
alias CQEx.Result

@create_astarte_keyspace """
CREATE KEYSPACE astarte
CREATE KEYSPACE #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())}
WITH
replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND
durable_writes = true;
"""

@create_autotestrealm """
CREATE KEYSPACE autotestrealm
CREATE KEYSPACE #{CQLUtils.realm_name_to_keyspace_name("autotestrealm", Config.astarte_instance_id!())}
WITH
replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND
durable_writes = true;
"""

@create_devices_table """
CREATE TABLE autotestrealm.devices (
CREATE TABLE #{CQLUtils.realm_name_to_keyspace_name("autotestrealm", Config.astarte_instance_id!())}.devices (
device_id uuid,
introspection map<ascii, int>,
introspection_minor map<ascii, int>,
Expand All @@ -67,7 +68,7 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
"""

@create_kv_store_table """
CREATE TABLE autotestrealm.kv_store (
CREATE TABLE #{CQLUtils.realm_name_to_keyspace_name("autotestrealm", Config.astarte_instance_id!())}.kv_store (
group varchar,
key varchar,
value blob,
Expand All @@ -77,7 +78,7 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
"""

@create_realms_table """
CREATE TABLE astarte.realms (
CREATE TABLE #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())}.realms (
realm_name varchar,
device_registration_limit bigint,
PRIMARY KEY (realm_name)
Expand All @@ -92,21 +93,21 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
"""

@insert_jwt_public_key_pem """
INSERT INTO autotestrealm.kv_store (group, key, value)
INSERT INTO #{CQLUtils.realm_name_to_keyspace_name("autotestrealm", Config.astarte_instance_id!())}.kv_store (group, key, value)
VALUES ('auth', 'jwt_public_key_pem', varcharAsBlob('#{@jwt_public_key_pem}'))
"""

@insert_autotestrealm_into_realms """
INSERT INTO astarte.realms (realm_name)
INSERT INTO #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())}.realms (realm_name)
VALUES ('autotestrealm');
"""

@drop_autotestrealm """
DROP KEYSPACE autotestrealm;
DROP KEYSPACE #{CQLUtils.realm_name_to_keyspace_name("autotestrealm", Config.astarte_instance_id!())};
"""

@drop_astarte_keyspace """
DROP KEYSPACE astarte;
DROP KEYSPACE #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())};
"""

@test_realm "autotestrealm"
Expand Down Expand Up @@ -186,7 +187,9 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
def seed_devices do
client =
Config.cassandra_node!()
|> Client.new!(keyspace: @test_realm)
|> Client.new!(
keyspace: CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

{:ok, registered_not_confirmed_device_id} =
Device.decode_device_id(@registered_not_confirmed_hw_id, allow_extended_id: true)
Expand Down Expand Up @@ -276,7 +279,9 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
def get_first_registration(hardware_id) do
client =
Config.cassandra_node!()
|> Client.new!(keyspace: @test_realm)
|> Client.new!(
keyspace: CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

{:ok, device_id} = Device.decode_device_id(hardware_id, allow_extended_id: true)

Expand All @@ -303,7 +308,9 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
def get_introspection(hardware_id) do
client =
Config.cassandra_node!()
|> Client.new!(keyspace: @test_realm)
|> Client.new!(
keyspace: CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

{:ok, device_id} = Device.decode_device_id(hardware_id, allow_extended_id: true)

Expand All @@ -327,7 +334,9 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
def get_introspection_minor(hardware_id) do
client =
Config.cassandra_node!()
|> Client.new!(keyspace: @test_realm)
|> Client.new!(
keyspace: CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

{:ok, device_id} = Device.decode_device_id(hardware_id, allow_extended_id: true)

Expand All @@ -351,7 +360,9 @@ defmodule Astarte.Pairing.DatabaseTestHelper do
def clean_devices do
client =
Config.cassandra_node!()
|> Client.new!(keyspace: @test_realm)
|> Client.new!(
keyspace: CQLUtils.realm_name_to_keyspace_name(@test_realm, Config.astarte_instance_id!())
)

Query.call!(client, "TRUNCATE devices")
# Also clean the cache
Expand All @@ -362,7 +373,7 @@ defmodule Astarte.Pairing.DatabaseTestHelper do

def set_device_registration_limit(realm_name, limit) do
query = """
UPDATE astarte.realms
UPDATE #{CQLUtils.realm_name_to_keyspace_name("astarte", Config.astarte_instance_id!())}.realms
SET device_registration_limit = :the_limit
WHERE realm_name = :realm_name
"""
Expand Down

0 comments on commit 55f242b

Please sign in to comment.