From 998965aac1b750130cd4b0894420fa3794413532 Mon Sep 17 00:00:00 2001 From: Davide Briani Date: Thu, 25 Jul 2024 16:01:56 +0200 Subject: [PATCH 1/3] astarte-dev-tool: add astarte_client dependency Add the Astarte Elixir client dependency to easily perform operations regarding Astarte realms and resources. Signed-off-by: Davide Briani --- tools/astarte_dev_tool/mix.exs | 4 +++- tools/astarte_dev_tool/mix.lock | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/astarte_dev_tool/mix.exs b/tools/astarte_dev_tool/mix.exs index 79a636800..221851036 100644 --- a/tools/astarte_dev_tool/mix.exs +++ b/tools/astarte_dev_tool/mix.exs @@ -38,6 +38,8 @@ defmodule AstarteDevTool.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do - [] + [ + {:astarte_client, github: "astarte-platform/astarte-client-elixir"} + ] end end diff --git a/tools/astarte_dev_tool/mix.lock b/tools/astarte_dev_tool/mix.lock index 0ac823b36..d9bc9e626 100644 --- a/tools/astarte_dev_tool/mix.lock +++ b/tools/astarte_dev_tool/mix.lock @@ -1,2 +1,16 @@ %{ + "astarte_client": {:git, "https://github.com/astarte-platform/astarte-client-elixir.git", "8286db6df9a43a2b5e30cdcdeb60ca5b38933559", []}, + "castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"}, + "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"}, + "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"}, + "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"}, + "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"}, + "x509": {:hex, :x509, "0.8.9", "03c47e507171507d3d3028d802f48dd575206af2ef00f764a900789dfbe17476", [:mix], [], "hexpm", "ea3fb16a870a199cb2c45908a2c3e89cc934f0434173dc0c828136f878f11661"}, } From 81899e2f5a0050f97f356c8981d1bdd597475291 Mon Sep 17 00:00:00 2001 From: Davide Briani Date: Thu, 25 Jul 2024 16:03:21 +0200 Subject: [PATCH 2/3] astarte-dev-tool: add dashboard.open command Add a new Mix task that opens an authenticated Astarte Dashboard session in the browser. Signed-off-by: Davide Briani --- .../lib/commands/dashboard/open.ex | 85 +++++++++++++++++++ .../tasks/astarte_dev_tool/dashboard/open.ex | 67 +++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 tools/astarte_dev_tool/lib/commands/dashboard/open.ex create mode 100644 tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/dashboard/open.ex diff --git a/tools/astarte_dev_tool/lib/commands/dashboard/open.ex b/tools/astarte_dev_tool/lib/commands/dashboard/open.ex new file mode 100644 index 000000000..e8d5b835c --- /dev/null +++ b/tools/astarte_dev_tool/lib/commands/dashboard/open.ex @@ -0,0 +1,85 @@ +# +# 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.Dashboard.Open do + @moduledoc false + + require Logger + + def exec(opts) do + dashboard_url = Keyword.get(opts, :dashboard_url, "http://dashboard.astarte.localhost/") + realm_name = Keyword.get(opts, :realm_name, "test") + private_key_path = Keyword.get(opts, :realm_private_key, "../../test_private.pem") + + {:ok, auth_token} = + with :error <- Keyword.fetch(opts, :auth_token) do + private_key = File.read!(private_key_path) + + Astarte.Client.Credentials.dashboard_credentials() + |> Astarte.Client.Credentials.to_jwt(private_key) + end + + authenticated_url = + dashboard_url + |> URI.new!() + |> URI.append_path("/auth") + |> URI.append_query("realm=" <> realm_name) + |> URI.to_string() + |> Kernel.<>("#access_token=" <> auth_token) + |> URI.encode() + + _ = open_in_browser(authenticated_url) + + {:ok, authenticated_url} + end + + defp open_in_browser(url) do + win_cmd_args = ["/c", "start", String.replace(url, "&", "^&")] + + cmd_args = + case :os.type() do + {:win32, _} -> + {"cmd", win_cmd_args} + + {:unix, :darwin} -> + {"open", [url]} + + {:unix, _} -> + cond do + System.find_executable("xdg-open") -> {"xdg-open", [url]} + # When inside WSL + System.find_executable("cmd.exe") -> {"cmd.exe", win_cmd_args} + true -> nil + end + end + + case cmd_args do + {cmd, args} -> + {_result, exit_status} = System.cmd(cmd, args) + + if exit_status == 0 do + :ok + else + :error + end + + nil -> + :error + end + end +end diff --git a/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/dashboard/open.ex b/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/dashboard/open.ex new file mode 100644 index 000000000..71fa81dc3 --- /dev/null +++ b/tools/astarte_dev_tool/lib/mix/tasks/astarte_dev_tool/dashboard/open.ex @@ -0,0 +1,67 @@ +# +# 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.Dashboard.Open do + use Mix.Task + alias AstarteDevTool.Commands.Dashboard + + @shortdoc "Open an authenticate Astarte Dashboard session" + + @aliases [ + r: :realm_name, + k: :realm_private_key, + t: :auth_token, + u: :dashboard_url + ] + + @switches [ + realm_name: :string, + realm_private_key: :string, + auth_token: :string, + dashboard_url: :string + ] + + @moduledoc """ + Open an authenticate Astarte Dashboard session. + + ## Examples + + $ mix dashboard.open -r test -k ../../test_private.pem + + ## Command line options + * `-r` `--realm-name` - The name of the Astarte realm. Defaults to 'test'. + + * `-k` `--realm-private-key` - The path of the private key for the Astarte + realm. Defaults to '../../test_private.pem'. + + * `-t` `--auth-token` - The auth token to use. If specified, it takes + precedence over the --realm-private-key option. + + * `-u` `--dashboard-url` - The URL of the Astarte Dashboard. It defaults + to 'http://dashboard.astarte.localhost'. + """ + + @impl true + def run(args) do + {opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases) + + {:ok, authenticated_url} = Dashboard.Open.exec(opts) + + Mix.Shell.IO.info("\nYou can access the Astarte Dashboard at:\n\n#{authenticated_url}") + end +end From d2220659b709b7b42b804287484a519ed8ed12a8 Mon Sep 17 00:00:00 2001 From: Davide Briani Date: Thu, 25 Jul 2024 16:04:09 +0200 Subject: [PATCH 3/3] astarte-dev-tool: document dashboard.open command Add a reference about the new dashboard.open command in the README.md file of the Astarte Dev tool. Signed-off-by: Davide Briani --- tools/astarte_dev_tool/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/astarte_dev_tool/README.md b/tools/astarte_dev_tool/README.md index 05de29581..c1f38c4ab 100644 --- a/tools/astarte_dev_tool/README.md +++ b/tools/astarte_dev_tool/README.md @@ -43,12 +43,27 @@ mix astarte_dev_tool.system.watch --path This command will start the system in watch mode and keep running in the foreground, allowing for real-time code reloading during development. +### Accessing the Dashboard + +To open an authenticated Dashboard session on your web browser: + +```bash +mix astarte_dev_tool.dashboard.open +``` + +where the following options can be specified: +- `--realm-name`, or `-r`, for the name of the Astarte realm. It defaults to `test`. +- `--realm-private-key`, or `-k`, for the path of the private key for the Astarte realm. It defaults to `../../test_private.pem`, which assumes the user has followed the [Astarte in 5 minutes guide](https://docs.astarte-platform.org/astarte/latest/010-astarte_in_5_minutes.html). +- `--auth-token`, or `-t`, for the auth token to use. If specified, it takes precedence over the `--realm-private-key` option. +- `--dashboard-url`, or `-u`, for the URL of the Astarte Dashboard. It defaults to `http://dashboard.astarte.localhost`. + --- ### Example 1. Start the system: `mix astarte_dev_tool.system.up --path ../../../astarte` 2. Enable watch mode: `mix astarte_dev_tool.system.watch --path ../../../astarte` +3. Open the Astarte Dashboard: `mix astarte_dev_tool.dashboard.open --realm-name test --realm-private-key ../../../astarte/test_private.pem` 3. Stop the system: `mix astarte_dev_tool.system.down --path ../../../astarte` These commands will help you manage the development environment for Astarte efficiently.