diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 15b3f3d50..f606c63fa 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -114,3 +114,6 @@ services: watch: - path: apps/astarte_trigger_engine/lib action: rebuild + scylla: + ports: + - "9042:9042" \ No newline at end of file diff --git a/tools/astarte_dev_tool/config/config.exs b/tools/astarte_dev_tool/config/config.exs new file mode 100644 index 000000000..488affe74 --- /dev/null +++ b/tools/astarte_dev_tool/config/config.exs @@ -0,0 +1,14 @@ +import Config + +config :logger, :console, + format: {PrettyLog.LogfmtFormatter, :format}, + metadata: [:realm, :datacenter, :replication_factor, :module, :function, :tag] + +config :astarte_dev_tool, :xandra, + nodes: [ + "#{System.get_env("CASSANDRA_DB_HOST") || "localhost"}:#{System.get_env("CASSANDRA_DB_PORT") || 9042}" + ], + sync_connect: 5000, + log: :info, + stacktrace: true, + pool_size: 10 diff --git a/tools/astarte_dev_tool/lib/commands/realm/create.ex b/tools/astarte_dev_tool/lib/commands/realm/create.ex new file mode 100644 index 000000000..a40d2c412 --- /dev/null +++ b/tools/astarte_dev_tool/lib/commands/realm/create.ex @@ -0,0 +1,54 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule AstarteDevTool.Commands.Realm.Create do + @moduledoc false + alias Astarte.DataAccess.Database + alias Astarte.DataAccess.Realm, as: RealmDataAccess + + @start_apps [ + :logger, + :crypto, + :ssl, + :xandra, + :astarte_data_access + ] + def exec( + [{_, _} | _] = nodes, + realm_name, + replication \\ 1, + max_retention \\ 1, + public_key_pem \\ "@@@@", + device_registration_limit \\ nil, + realm_schema_version \\ 10 + ) do + with :ok <- Enum.each(@start_apps, &Application.ensure_all_started/1), + {:ok, _client} <- Database.connect(cassandra_nodes: nodes), + :ok <- + RealmDataAccess.create_realm( + realm_name, + replication, + max_retention, + public_key_pem, + device_registration_limit, + realm_schema_version + ) do + :ok + end + end +end diff --git a/tools/astarte_dev_tool/lib/commands/system/check.ex b/tools/astarte_dev_tool/lib/commands/system/check.ex new file mode 100644 index 000000000..edfe128ce --- /dev/null +++ b/tools/astarte_dev_tool/lib/commands/system/check.ex @@ -0,0 +1,54 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule AstarteDevTool.Commands.System.Check do + @moduledoc false + require Logger + alias AstarteDevTool.Utilities.System, as: SystemUtilities + + @astarte_services [ + "astarte-dashboard", + "astarte-appengine-api", + "astarte-housekeeping", + "astarte-housekeeping-api", + "astarte-grafana", + "astarte-realm-management", + "astarte-realm-management-api", + "astarte-data-updater-plant", + "astarte-trigger-engine", + "astarte-pairing", + "astarte-pairing-api", + "vernemq", + "scylla", + "traefik", + "rabbitmq", + "cfssl" + ] + + def exec(path) do + case SystemUtilities.system_status(path) do + {:ok, list} -> + current_list = list |> Enum.map(fn %{"name" => name} -> name end) |> MapSet.new() + + case Enum.filter(@astarte_services, &(not MapSet.member?(current_list, &1))) do + [] -> :ok + rest -> {:error, rest} + end + end + end +end diff --git a/tools/astarte_dev_tool/lib/commands/system/watch.ex b/tools/astarte_dev_tool/lib/commands/system/watch.ex index a1921eb3d..51cb4c8a2 100644 --- a/tools/astarte_dev_tool/lib/commands/system/watch.ex +++ b/tools/astarte_dev_tool/lib/commands/system/watch.ex @@ -20,10 +20,10 @@ defmodule AstarteDevTool.Commands.System.Watch do @moduledoc false require Logger alias AstarteDevTool.Constants.System, as: Constants - alias AstarteDevTool.Utilities.Process, as: AstarteProcess + alias AstarteDevTool.Utilities.Process, as: ProcessUtilities def exec(path) do - case AstarteProcess.check_process(Constants.command(), Constants.command_watch_args(), path) do + case ProcessUtilities.process_check(Constants.command(), Constants.command_watch_args(), path) do {:ok, pid} when not is_nil(pid) -> kill_zombie_process(pid) _ -> :ok end diff --git a/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/realm/create.ex b/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/realm/create.ex new file mode 100644 index 000000000..747f1cf6b --- /dev/null +++ b/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/realm/create.ex @@ -0,0 +1,97 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule Mix.Tasks.AstarteDevTool.Realm.Create do + use Mix.Task + alias Astarte.Core.Realm + alias AstarteDevTool.Utilities.Node + alias AstarteDevTool.Commands.Realm.Create + alias AstarteDevTool.Utilities.Path + + @shortdoc "Create realm/s into the running Astarte" + + @aliases [ + p: :path, + n: :node + ] + + @switches [ + path: :string, + node: :keep, + log_level: :string + ] + + @moduledoc """ + Create realm into the running Astarte platform. + + ## Examples + + $ mix astarte_dev_tool.realm.create -n localhost:12345 realm1 + $ mix astarte_dev_tool.realm.create -n localhost:12345 -n cassandra:54321 realm1 + + ## Command line options + * `-p` `--path` - (required) working Astarte project directory + + * `-n` `--node` - (at least one is required) Cassandra/Scylla cluster node. + Every node has format **host/ip:port** + + * `--log-level` - the level to set for `Logger`. This task + does not start your application, so whatever level you have configured in + your config files will not be used. If this is not provided, no level + will be set, so that if you set it yourself before calling this task + then this won't interfere. Can be any of the `t:Logger.level/0` levels + """ + + @impl true + def run(args) do + {opts, args} = OptionParser.parse!(args, strict: @switches, aliases: @aliases) + + unless Keyword.has_key?(opts, :path), do: Mix.raise("The --path argument is required") + + unless Keyword.has_key?(opts, :node), + do: Mix.raise("At least one --node argument is required") + + unless Enum.count(args) === 1, + do: Mix.raise("The command required one argument - the Realm name") + + realm_name = Enum.at(args, 0) + + unless Realm.valid_name?(realm_name), + do: Mix.raise("Invalid Realm name provided") + + nodes = + case(opts |> Keyword.get_values(:node) |> Node.parse_nodes()) do + {:ok, nodes} -> nodes + {:error, _} -> Mix.raise("--node argument must be in : format") + end + + if log_level = opts[:log_level], + do: Logger.configure(level: String.to_existing_atom(log_level)) + + with path <- opts[:path], + {:ok, abs_path} <- Path.directory_path_from(path), + :ok <- Mix.Tasks.AstarteDevTool.System.Check.run(["-p", abs_path]), + :ok <- Create.exec(nodes, realm_name) do + Mix.shell().info("Realms created successfully.") + :ok + else + {:error, output} -> + Mix.raise("Failed to create Astarte's realms. Output: #{output}") + end + end +end diff --git a/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/system/check.ex b/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/system/check.ex new file mode 100644 index 000000000..b2cec3549 --- /dev/null +++ b/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/system/check.ex @@ -0,0 +1,78 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule Mix.Tasks.AstarteDevTool.System.Check do + use Mix.Task + alias AstarteDevTool.Commands.System.Check + alias AstarteDevTool.Utilities.Path + + @shortdoc "Check if the current Astarte is up & running" + + @aliases [ + p: :path + ] + + @switches [ + path: :string, + log_level: :string + ] + + @moduledoc """ + Check if the current Astarte is up & running. + + ## Examples + + $ mix astarte_dev_tool.system.check -p /absolute/path/astarte + $ mix astarte_dev_tool.system.check -p ../../relative/to/astarte + + ## Command line options + * `-p` `--path` - (required) working Astarte project directory + + * `--log-level` - the level to set for `Logger`. This task + does not start your application, so whatever level you have configured in + your config files will not be used. If this is not provided, no level + will be set, so that if you set it yourself before calling this task + then this won't interfere. Can be any of the `t:Logger.level/0` levels + """ + + @impl true + def run(args) do + {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases) + + unless Keyword.has_key?(opts, :path), do: Mix.raise("The --path argument is required") + + if log_level = opts[:log_level], + do: Logger.configure(level: String.to_existing_atom(log_level)) + + with path <- opts[:path], + {:ok, abs_path} <- Path.directory_path_from(path) do + case Check.exec(abs_path) do + :ok -> + Mix.shell().info("All Astarte's services are up & ready") + :ok + + {:error, list} = data -> + Mix.raise("Some Astarte's services do not seem to be working: #{list}") + data + end + else + {:error, output} -> + Mix.raise("Failed to check Astarte's system. Output: #{output}") + end + end +end diff --git a/tools/astarte_dev_tool/lib/utilities/node.ex b/tools/astarte_dev_tool/lib/utilities/node.ex new file mode 100644 index 000000000..130b10e81 --- /dev/null +++ b/tools/astarte_dev_tool/lib/utilities/node.ex @@ -0,0 +1,36 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule AstarteDevTool.Utilities.Node do + @host_regex ~r/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/ + @ip_regex ~r/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/ + @port_regex ~r/^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$/ + + def parse_nodes(list), do: parse_nodes(list, []) + + defp parse_nodes([], acc), do: {:ok, acc} + + defp parse_nodes([str | t], acc) do + with [host, port] <- String.split(str, ":"), + true <- (host =~ @host_regex or host =~ @ip_regex) and port =~ @port_regex do + parse_nodes(t, [{host, port} | acc]) + else + _ -> {:error, "Invalid format"} + end + end +end diff --git a/tools/astarte_dev_tool/lib/utilities/process.ex b/tools/astarte_dev_tool/lib/utilities/process.ex index 5fed313d2..26c73ad63 100644 --- a/tools/astarte_dev_tool/lib/utilities/process.ex +++ b/tools/astarte_dev_tool/lib/utilities/process.ex @@ -44,8 +44,6 @@ defmodule AstarteDevTool.Utilities.Process do end end - defp clean_version(version), do: {:ok, version |> String.trim() |> String.trim("'")} - def check_process(command, args, path) when is_list(args) do command = "#{command} #{Enum.join(args, "")}" check_process(command, path) @@ -58,17 +56,18 @@ defmodule AstarteDevTool.Utilities.Process do end end - defp find_pids_by_command(command) do - case System.cmd("pgrep", ["-f", command]) do - {pids_str, 0} -> {:ok, String.trim(pids_str) |> String.split("\n")} - _ -> {:ok, []} - end - end + defp clean_version(version), do: {:ok, version |> String.trim() |> String.trim("'")} - defp find_pid_by_path([], _path), do: {:ok, nil} + def process_check(command, args, path) when is_list(args) do + command = "#{command} #{Enum.join(args, "")}" + process_check(command, path) + end - defp find_pid_by_path([pid | rest], path) do - if process_matches_path?(pid, path), do: {:ok, pid}, else: find_pid_by_path(rest, path) + def process_check(command, path) when is_bitstring(command) and is_bitstring(path) do + with {:ok, pids} <- find_pids_by_command(command), + {:ok, pid} <- find_pid_by_path(pids, path) do + {:ok, pid} + end end def process_matches_path?(pid, path) do @@ -85,4 +84,17 @@ defmodule AstarteDevTool.Utilities.Process do cwd == path end + + defp find_pids_by_command(command) do + case System.cmd("pgrep", ["-f", command]) do + {pids_str, 0} -> {:ok, String.trim(pids_str) |> String.split("\n")} + _ -> {:ok, []} + end + end + + defp find_pid_by_path([], _path), do: {:ok, nil} + + defp find_pid_by_path([pid | rest], path) do + if process_matches_path?(pid, path), do: {:ok, pid}, else: find_pid_by_path(rest, path) + end end diff --git a/tools/astarte_dev_tool/lib/utilities/system.ex b/tools/astarte_dev_tool/lib/utilities/system.ex new file mode 100644 index 000000000..229254297 --- /dev/null +++ b/tools/astarte_dev_tool/lib/utilities/system.ex @@ -0,0 +1,36 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule AstarteDevTool.Utilities.System do + @field_separator "," + @parse_regex ~r/^(?\w+)#{@field_separator}(?:astarte-(?[\w-]+)-\d)$/ + + def system_status(path) do + command = "docker" + + args = + ~w(ps -a --no-trunc --format {{.ID}}#{@field_separator}{{.Names}} -f status=running -f label=com.docker.compose.project.working_dir=#{path}) + + {pids_str, 0} = System.cmd(command, args, cd: path) + + {:ok, + pids_str + |> String.split("\n", trim: true) + |> Enum.map(&Regex.named_captures(@parse_regex, &1))} + end +end diff --git a/tools/astarte_dev_tool/mix.exs b/tools/astarte_dev_tool/mix.exs index 733909579..9f22e06fe 100644 --- a/tools/astarte_dev_tool/mix.exs +++ b/tools/astarte_dev_tool/mix.exs @@ -32,7 +32,7 @@ defmodule AstarteDevTool.MixProject do # Run "mix help compile.app" to learn about applications. def application do [ - extra_applications: [:logger] + extra_applications: [:logger, :xandra, :astarte_core, :astarte_data_access] ] end @@ -40,6 +40,9 @@ defmodule AstarteDevTool.MixProject do defp deps do [ {:x509, "~> 0.8"}, + {:xandra, "~> 0.19"}, + {:astarte_core, github: "astarte-platform/astarte_core"}, + {:astarte_data_access, path: "/home/ghio/Documents/astarte_data_access"}, {:astarte_client, github: "astarte-platform/astarte-client-elixir"} ] end diff --git a/tools/astarte_dev_tool/mix.lock b/tools/astarte_dev_tool/mix.lock index d9bc9e626..e68a352a4 100644 --- a/tools/astarte_dev_tool/mix.lock +++ b/tools/astarte_dev_tool/mix.lock @@ -1,16 +1,40 @@ %{ "astarte_client": {:git, "https://github.com/astarte-platform/astarte-client-elixir.git", "8286db6df9a43a2b5e30cdcdeb60ca5b38933559", []}, + "astarte_core": {:git, "https://github.com/astarte-platform/astarte_core.git", "6d2f92a63fdc495ca6031e5cbdfbfb58b62b2660", []}, + "astarte_data_access": {:git, "https://github.com/astarte-platform/astarte_data_access.git", "5b7f25eded8d5c0d3492c2622c33ff2d961acb46", []}, "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, + "cqerl": {:hex, :cqerl, "2.0.1", "c92929e885adc50cda1f11b73eb0121363e8418533312f8a44defb5f14853445", [:rebar3], [{:lz4, "~> 0.2.4", [hex: :lz4_erl, repo: "hexpm", optional: false]}, {:re2, "1.9.5", [hex: :re2, repo: "hexpm", optional: false]}, {:semver, "~> 0.0.1", [hex: :semver_erl, repo: "hexpm", optional: false]}, {:snappyer, "1.2.6", [hex: :snappyer, repo: "hexpm", optional: false]}, {:uuid, "~> 2.0.0", [hex: :uuid_erl, repo: "hexpm", optional: false]}], "hexpm", "96e9ee407830508187a5edff9fc49983a7122b5c4127c640320a226b59ae12fe"}, + "cqex": {:hex, :cqex, "1.0.1", "bc9980ac3b82d039879f8d6ca589deab799fe08f80ff449d60ad709f2524718f", [:mix], [{:cqerl, "~> 2.0.1", [hex: :cqerl, repo: "hexpm", optional: false]}], "hexpm", "1bbf2079c044cbf0f747f60dcf0409a951eaa8f1a2447cd6d80d6ff1b7c4dc6b"}, + "curvy": {:hex, :curvy, "0.3.1", "2645a11452743a37de2393da4d2e60700632498b166413b4f73bc34c57a911e1", [:mix], [], "hexpm", "82df293452f7b751becabc29e8aad0f7d88ffdcd790ac7a2ea16ea1544681d8a"}, + "cyanide": {:hex, :cyanide, "2.0.0", "f97b700b87f9b0679ae812f0c4b7fe35ea6541a4121a096cf10287941b7a6d55", [:mix], [], "hexpm", "7f9748251804c2a2115b539202568e1117ab2f0ae09875853fb89cc94ae19dd1"}, + "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"}, + "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, + "ecto": {:hex, :ecto, "3.12.1", "626765f7066589de6fa09e0876a253ff60c3d00870dd3a1cd696e2ba67bfceea", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df0045ab9d87be947228e05a8d153f3e06e0d05ab10c3b3cc557d2f7243d1940"}, + "ecto_morph": {:hex, :ecto_morph, "0.1.29", "bc0b915779636bd2d30c54cad6922b3cb40f85b1d4ad59bdffd3c788d9d1f972", [:mix], [{:ecto, ">= 3.0.3", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "814bed72e3d03b278c1dfb3fbc4da37f478a37518ee54f010c1ad9254f1ca0e3"}, + "ecto_sql": {:hex, :ecto_sql, "3.12.0", "73cea17edfa54bde76ee8561b30d29ea08f630959685006d9c6e7d1e59113b7d", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dc9e4d206f274f3947e96142a8fdc5f69a2a6a9abb4649ef5c882323b6d512f0"}, + "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, + "ex_crypto": {:hex, :ex_crypto, "0.10.0", "af600a89b784b36613a989da6e998c1b200ff1214c3cfbaf8deca4aa2f0a1739", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "ccc7472cfe8a0f4565f97dce7e9280119bf15a5ea51c6535e5b65f00660cde1c"}, + "exandra": {:hex, :exandra, "0.10.2", "e95dca77501df9ae48f23854224e91712e64d65cd7157e2fe46232ea97918ec6", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:xandra, "~> 0.18.0", [hex: :xandra, repo: "hexpm", optional: false]}], "hexpm", "334616b170233828f2acac0b060c3c6c91051848972218d2b159e3a455b07c84"}, "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, - "jason": {:hex, :jason, "1.4.3", "d3f984eeb96fe53b85d20e0b049f03e57d075b5acda3ac8d465c969a2536c17b", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9a90e868927f7c777689baa16d86f4d0e086d968db5c05d917ccff6d443e58a3"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "joken": {:hex, :joken, "2.6.1", "2ca3d8d7f83bf7196296a3d9b2ecda421a404634bfc618159981a960020480a1", [:mix], [{:jose, "~> 1.11.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "ab26122c400b3d254ce7d86ed066d6afad27e70416df947cdcb01e13a7382e68"}, "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, + "lz4": {:hex, :lz4_erl, "0.2.4", "fafc1fa39ed1d034893316852daebedd82f37df478446224ac096490be3b4a4d", [:rebar3], [], "hexpm", "e3eb9e2b5c1e4dab39db8fe0421e6fa10f9bf5843f20dab43518f8ab8e812517"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, - "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "poison": {:hex, :poison, "6.0.0", "9bbe86722355e36ffb62c51a552719534257ba53f3271dacd20fbbd6621a583a", [:mix], [{:decimal, "~> 2.1", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "bb9064632b94775a3964642d6a78281c07b7be1319e0016e1643790704e739a2"}, + "protobuf": {:hex, :protobuf, "0.12.0", "58c0dfea5f929b96b5aa54ec02b7130688f09d2de5ddc521d696eec2a015b223", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "75fa6cbf262062073dd51be44dd0ab940500e18386a6c4e87d5819a58964dc45"}, + "quickrand": {:hex, :quickrand, "2.0.7", "d2bd76676a446e6a058d678444b7fda1387b813710d1af6d6e29bb92186c8820", [:rebar3], [], "hexpm", "b8acbf89a224bc217c3070ca8bebc6eb236dbe7f9767993b274084ea044d35f0"}, + "re2": {:hex, :re2, "1.9.5", "3c419527fb2cc75eda1657f04dc7e8cea9864899b43ff6cc3250fa7525431e83", [:rebar3], [], "hexpm", "4861336271ac565224e79e133cbaf90af77739cda3fff25f6965b24a1146a4d6"}, + "semver": {:hex, :semver_erl, "0.0.1", "e1dc99fb20ff071b240a0280611faba93eeb9c2adfb02a15e20a06a9f13dfff4", [:rebar3], [], "hexpm", "adf1cb935eeb2472b4b7bb8116c678c1077ae4cd5bdfe90010b765aecce5753b"}, + "skogsra": {:hex, :skogsra, "2.5.0", "57d57c15bb8356662177779cb10adf1272069eeb4f3c032bf7d71d522e726f06", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: true]}], "hexpm", "b7dfe23ef3f9999a96fa330b73363b3f48d68a7ca3eb98ab1f32cd888ef207ee"}, + "snappyer": {:hex, :snappyer, "1.2.6", "34181e3233f68a92044e176fe96e54fee7957acc2be554f0460d799c495166c2", [:rebar3], [], "hexpm", "d538d1e8892af09dc8b2771b2652c9d70f009cd1556246b3e22706df643f47b4"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "tesla": {:hex, :tesla, "1.11.2", "24707ac48b52f72f88fc05d242b1c59a85d1ee6f16f19c312d7d3419665c9cd5", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "c549cd03aec6a7196a641689dd378b799e635eb393f689b4bd756f750c7a4014"}, + "uuid": {:hex, :uuid_erl, "2.0.7", "b2078d2cc814f53afa52d36c91e08962c7e7373585c623f4c0ea6dfb04b2af94", [:rebar3], [{:quickrand, ">= 2.0.7", [hex: :quickrand, repo: "hexpm", optional: false]}], "hexpm", "4e4c5ca3461dc47c5e157ed42aa3981a053b7a186792af972a27b14a9489324e"}, "x509": {:hex, :x509, "0.8.9", "03c47e507171507d3d3028d802f48dd575206af2ef00f764a900789dfbe17476", [:mix], [], "hexpm", "ea3fb16a870a199cb2c45908a2c3e89cc934f0434173dc0c828136f878f11661"}, + "xandra": {:hex, :xandra, "0.19.1", "3041768e92874d850f65905669fb39a9482e4b68059351efc09ddc881f1e0baa", [:mix], [{:decimal, "~> 1.7 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f47cef0597ff04baf1416dc3c4906c6edb04f19f7081a523f8eee1d3b69a4323"}, } diff --git a/tools/astarte_dev_tool/test/realm_test.exs b/tools/astarte_dev_tool/test/realm_test.exs new file mode 100644 index 000000000..4c0ff9b88 --- /dev/null +++ b/tools/astarte_dev_tool/test/realm_test.exs @@ -0,0 +1,48 @@ +# +# This file is part of Astarte. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +defmodule AstarteDevToolTest.Realm do + use ExUnit.Case + alias AstarteDevTool.Commands.Realm + + @nodes [ + {"localhost", "9042"} + ] + + @realm "realm1" + + @doctest false + @moduletag :realm + describe "unit test" do + test "1" do + assert true + end + + test "2" do + assert :ok = Realm.Create.exec(@nodes, @realm) + end + end + + describe "mix tasks" do + test "1" do + # {:ok, private} = Mix.Tasks.AstarteDevTool.Auth.Keys.run([]) + # {:ok, public} = Mix.Tasks.AstarteDevTool.Auth.Keys.run(["--", private]) + assert 1 + end + end +end