diff --git a/lib/incident_api.ex b/lib/incident_api.ex index 123fe40..79411cd 100644 --- a/lib/incident_api.ex +++ b/lib/incident_api.ex @@ -1,82 +1,94 @@ defmodule LogpointApi.IncidentApi do @moduledoc """ This module provides an implementation of the Logpoint Incident API. - - ## Modules - - - `TimeRange` : A struct used to represent a time range. - - `Incident` : A struct used to represent an incident. - - `IncidentComment` : A struct used to represent an incident comment. - - `IncidentCommentData` : A struct used to represent incident comment data. - - `IncidentIDs` : A struct used to represent incident IDs. - - ## Public Functions - - - `get_incidents/3` : Retrieves incidents within a specified time range. - - `get_data_from_incident/3` : Retrieves data from a specific incident. - - `get_incident_states/3` : Retrieves incident states within a specified time range. - - `get_users/2` : Retrieves user data. - - `add_comments/3` : Adds comments to an incident. - - `assign_incidents/4` : Assigns incidents to a user. - - `resolve_incidents/3` : Resolves incidents. - - `reopen_incidents/3` : Reopens incidents. - - `close_incidents/3` : Closes incidents. """ alias LogpointApi.Credential - alias LogpointApi.IncidentApi.{Incident, IncidentComment, IncidentCommentData, IncidentIDs, TimeRange} defmodule TimeRange do + @moduledoc """ + Struct representing a time range with timestamps in epoch. + """ @derive {Jason.Encoder, only: [:version, :ts_from, :ts_to]} defstruct [:ts_from, :ts_to, version: "0.1"] end defmodule Incident do + @moduledoc """ + Struct used to fetch an incident. + """ @derive {Jason.Encoder, only: [:incident_obj_id, :incident_id]} defstruct [:incident_obj_id, :incident_id] end defmodule IncidentComment do + @moduledoc """ + Struct to add comments to a particular incident. + """ @derive {Jason.Encoder, only: [:_id, :comments]} defstruct _id: "", comments: [] end defmodule IncidentCommentData do + @moduledoc """ + Struct to add comments to a list of incidents using the `IncidentComment` struct. + """ @derive {Jason.Encoder, only: [:version, :states]} defstruct version: "0.1", states: [%IncidentComment{}] end defmodule IncidentIDs do + @moduledoc """ + Struct that represents a list of incidents. + """ @derive {Jason.Encoder, only: [:version, :incident_ids]} defstruct version: "0.1", incident_ids: [] end + @doc """ + Get all incidents within a given time range. + """ @spec get_incidents(String.t(), Credential.t(), TimeRange.t()) :: {:ok, map()} | {:error, String.t()} def get_incidents(ip, credential, %TimeRange{} = time_range), do: get_incident_information(ip, "/incidents", credential, time_range) + @doc """ + Get a specific incident and its related data. + """ @spec get_data_from_incident(String.t(), Credential.t(), Incident.t()) :: {:ok, map()} | {:error, String.t()} def get_data_from_incident(ip, credential, %Incident{} = incident), do: get_incident_information(ip, "/get_data_from_incident", credential, incident) + @doc """ + Get the states of incidents within a specific time range. + """ @spec get_incident_states(String.t(), Credential.t(), TimeRange.t()) :: {:ok, map()} | {:error, String.t()} def get_incident_states(ip, credential, %TimeRange{} = time_range), do: get_incident_information(ip, "/incident_states", credential, time_range) + @doc """ + Get users. + """ @spec get_users(String.t(), Credential.t()) :: {:ok, map()} | {:error, String.t()} def get_users(ip, credential) do payload = make_payload(credential) make_request(ip, "/get_users", :get, payload) end + @doc """ + Add comments to a list of incidents. + """ @spec add_comments(String.t(), Credential.t(), IncidentCommentData.t()) :: {:ok, map()} | {:error, String.t()} def add_comments(ip, credential, %IncidentCommentData{} = incident_comment_data), do: update_incident_state(ip, "/add_incident_comment", credential, incident_comment_data) + @doc """ + Assign or re-assign a list of incidents. + """ @spec assign_incidents(String.t(), Credential.t(), IncidentIDs.t(), String.t()) :: {:ok, map()} | {:error, String.t()} def assign_incidents(ip, credential, %IncidentIDs{} = incident_ids, assignee_id) do @@ -84,21 +96,31 @@ defmodule LogpointApi.IncidentApi do update_incident_state(ip, "/assign_incident", credential, payload) end + @doc """ + Resolve a list of incidents. + """ @spec resolve_incidents(String.t(), Credential.t(), IncidentIDs.t()) :: {:ok, map()} | {:error, String.t()} def resolve_incidents(ip, credential, %IncidentIDs{} = incident_ids), do: update_incident_state(ip, "/resolve_incident", credential, incident_ids) + @doc """ + Reopen a list of incidents. + """ @spec reopen_incidents(String.t(), Credential.t(), IncidentIDs.t()) :: {:ok, map()} | {:error, String.t()} def reopen_incidents(ip, credential, %IncidentIDs{} = incident_ids), do: update_incident_state(ip, "/reopen_incident", credential, incident_ids) + @doc """ + Close a list of incidents. + """ @spec close_incidents(String.t(), Credential.t(), IncidentIDs.t()) :: {:ok, map()} | {:error, String.t()} def close_incidents(ip, credential, %IncidentIDs{} = incident_ids), do: update_incident_state(ip, "/close_incident", credential, incident_ids) + @doc false @spec update_incident_state(String.t(), String.t(), Credential.t(), map()) :: {:ok, map()} | {:error, String.t()} defp update_incident_state(ip, path, credential, request_data) do @@ -106,6 +128,7 @@ defmodule LogpointApi.IncidentApi do make_request(ip, path, :post, payload) end + @doc false @spec get_incident_information(String.t(), String.t(), Credential.t(), map()) :: {:ok, map()} | {:error, String.t()} defp get_incident_information(ip, path, credential, request_data) do @@ -113,6 +136,7 @@ defmodule LogpointApi.IncidentApi do make_request(ip, path, :get, payload) end + @doc false @spec make_request(String.t(), String.t(), atom(), String.t()) :: {:ok, map()} | {:error, String.t()} defp make_request(ip, path, method, payload) do url = build_url(ip, path) @@ -132,9 +156,11 @@ defmodule LogpointApi.IncidentApi do end end + @doc false @spec build_url(String.t(), String.t()) :: String.t() defp build_url(ip, path), do: "https://" <> ip <> path + @doc false @spec make_payload(Credential.t(), map()) :: String.t() defp make_payload(%Credential{} = credential, request_data) do %{ @@ -145,6 +171,7 @@ defmodule LogpointApi.IncidentApi do |> Jason.encode!() end + @doc false @spec make_payload(Credential.t()) :: String.t() defp make_payload(%Credential{} = credential) do %{ diff --git a/lib/logpoint_api.ex b/lib/logpoint_api.ex index 2c9a2fe..449fb2d 100644 --- a/lib/logpoint_api.ex +++ b/lib/logpoint_api.ex @@ -1,5 +1,10 @@ defmodule LogpointApi do + @moduledoc false + defmodule Credential do + @moduledoc """ + Struct representing credentials used for authorization. + """ defstruct [:username, :secret_key] end end diff --git a/lib/search_api.ex b/lib/search_api.ex index 2dcbcb4..ae6fc9b 100644 --- a/lib/search_api.ex +++ b/lib/search_api.ex @@ -1,25 +1,6 @@ defmodule LogpointApi.SearchApi do @moduledoc """ This module provides an implementation of the Logpoint search API. - - ## Modules - - - `Query` : A struct used to represent a search query. - - `SearchID` : A struct used to represent a search ID. - - ## Constants - - - `@allowed_types` : A list of allowed types for data retrieval. - - ## Public Functions - - - `get_user_timezone/2` : Retrieves user timezone data. - - `get_logpoints/2` : Retrieves logpoints data. - - `get_repos/2` : Retrieves repositories data. - - `get_devices/2` : Retrieves devices data. - - `get_livesearches/2` : Retrieves live searches data. - - `get_search_id/3` : Creates a search in Logpoint and returns the JSON object. - - `get_search_result/3` : Retrieves search results for a given search ID. """ alias LogpointApi.Credential @@ -28,45 +9,73 @@ defmodule LogpointApi.SearchApi do @allowed_types ["user_preference", "loginspects", "logpoint_repos", "devices", "livesearches"] defmodule Query do + @moduledoc """ + Struct representing a Logpoint search query. + """ @derive {Jason.Encoder, only: [:query, :time_range, :limit, :repos]} defstruct [:query, :time_range, :limit, :repos] end defmodule SearchID do + @moduledoc """ + Struct representing a search id. + """ @derive {Jason.Encoder, only: [:search_id]} defstruct [:search_id] end + @doc """ + Get the current users time zone information. + """ @spec get_user_timezone(String.t(), Credential.t()) :: {:ok, map()} | {:error, String.t()} def get_user_timezone(ip, credential), do: get_allowed_data(ip, credential, "user_preference") + @doc """ + Get all logpoints of a Logpoint instance. + """ @spec get_logpoints(String.t(), Credential.t()) :: {:ok, map()} | {:error, String.t()} def get_logpoints(ip, credential), do: get_allowed_data(ip, credential, "loginspects") + @doc """ + Get the repos of an instance. + """ @spec get_repos(String.t(), Credential.t()) :: {:ok, map()} | {:error, String.t()} def get_repos(ip, credential), do: get_allowed_data(ip, credential, "logpoint_repos") + @doc """ + Get the devices of the instance. + """ @spec get_devices(String.t(), Credential.t()) :: {:ok, map()} | {:error, String.t()} def get_devices(ip, credential), do: get_allowed_data(ip, credential, "devices") + @doc """ + Get all live search on a machine. + """ @spec get_livesearches(String.t(), Credential.t()) :: {:ok, map()} | {:error, String.t()} def get_livesearches(ip, credential), do: get_allowed_data(ip, credential, "livesearches") + @doc """ + Create a search and get its search id. + """ @spec get_search_id(String.t(), Credential.t(), Query.t()) :: {:ok, map()} | {:error, String.t()} def get_search_id(ip, credential, %Query{} = query), do: get_search_logs(ip, credential, query) + @doc """ + Retrieve the search result of a specific search id. + """ @spec get_search_result(String.t(), Credential.t(), SearchID.t()) :: {:ok, map()} | {:error, String.t()} def get_search_result(ip, credential, %SearchID{} = search_id), do: get_search_logs(ip, credential, search_id) + @doc false @spec make_request(String.t(), String.t(), String.t()) :: {:ok, map()} | {:error, String.t()} defp make_request(ip, path, payload) do url = build_url(ip, path) @@ -86,21 +95,25 @@ defmodule LogpointApi.SearchApi do end end + @doc false @spec build_url(String.t(), String.t()) :: String.t() defp build_url(ip, path), do: "https://" <> ip <> path + @doc false @spec get_allowed_data(String.t(), Credential.t(), String.t()) :: {:ok, map()} | {:error, String.t()} defp get_allowed_data(ip, credential, type) when type in @allowed_types do payload = build_payload(credential, %{"type" => type}) make_request(ip, "/getalloweddata", payload) end + @doc false @spec get_search_logs(String.t(), Credential.t(), map()) :: {:ok, map()} | {:error, String.t()} defp get_search_logs(ip, credential, request_data) do payload = build_payload(credential, %{"requestData" => Jason.encode!(request_data)}) make_request(ip, "/getsearchlogs", payload) end + @doc false @spec build_payload(Credential.t(), map()) :: String.t() defp build_payload(%Credential{} = credential, data) do Map.merge( diff --git a/mix.exs b/mix.exs index 145c449..1261ac5 100644 --- a/mix.exs +++ b/mix.exs @@ -22,7 +22,8 @@ defmodule LogpointApi.MixProject do defp deps do [ {:httpoison, "~> 2.0"}, - {:jason, "~> 1.4.1"} + {:jason, "~> 1.4"}, + {:ex_doc, "~> 0.21", only: :dev, runtime: false} ] end end diff --git a/mix.lock b/mix.lock index 818bbaf..f2bd2ac 100644 --- a/mix.lock +++ b/mix.lock @@ -1,11 +1,17 @@ %{ "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, + "ex_doc": {:hex, :ex_doc, "0.32.1", "21e40f939515373bcdc9cffe65f3b3543f05015ac6c3d01d991874129d173420", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5142c9db521f106d61ff33250f779807ed2a88620e472ac95dc7d59c380113da"}, "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},