Skip to content

Commit

Permalink
Add snapshot restore
Browse files Browse the repository at this point in the history
  • Loading branch information
Clivern committed Mar 31, 2024
1 parent 87c162e commit 6e0aeb5
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 7 deletions.
35 changes: 34 additions & 1 deletion lib/lynx/module/snapshot_module.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Lynx.Module.SnapshotModule do
alias Lynx.Context.ProjectContext
alias Lynx.Context.EnvironmentContext
alias Lynx.Context.StateContext
alias Lynx.Module.TaskModule

@doc """
Get Snapshot by UUID
Expand Down Expand Up @@ -100,6 +101,38 @@ defmodule Lynx.Module.SnapshotModule do
SnapshotContext.count_snapshots_by_teams(teams_ids)
end

@doc """
Restore Snapshots By UUID
"""
def restore_snapshot_by_uuid(uuid) do
case get_snapshot_by_uuid(uuid) do
{:ok, snapshot} ->
result =
TaskModule.create_task(%{
payload:
Jason.encode!(%{
action: "restore_snapshot",
snapshot_uuid: snapshot.uuid,
snapshot_id: snapshot.id
}),
result: "{}",
status: "pending",
run_at: DateTime.utc_now()
})

case result do
{:error, msg} ->
{:error, msg}

{:ok, task} ->
{:ok, task}
end

{:not_found, msg} ->
{:not_found, msg}
end
end

@doc """
Take Snapshot
"""
Expand All @@ -122,7 +155,7 @@ defmodule Lynx.Module.SnapshotModule do
@doc """
Restore Snapshot
"""
def restore_snapshot(uuid) do
def restore_snapshot(_uuid) do
end

def project_snapshot_data(uuid) do
Expand Down
25 changes: 25 additions & 0 deletions lib/lynx/module/task_module.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,31 @@ defmodule Lynx.Module.TaskModule do

alias Lynx.Context.TaskContext

@doc """
Create Task
"""
def create_task(data \\ %{}) do
task =
TaskContext.new_task(%{
payload: data[:payload],
result: data[:result],
status: data[:status],
run_at: data[:run_at]
})

case TaskContext.create_task(task) do
{:ok, task} ->
{:ok, task}

{:error, changeset} ->
messages =
changeset.errors()
|> Enum.map(fn {field, {message, _options}} -> "#{field}: #{message}" end)

{:error, Enum.at(messages, 0)}
end
end

@doc """
Get task by UUID
"""
Expand Down
6 changes: 3 additions & 3 deletions lib/lynx/worker/snapshot.ex
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ defmodule Lynx.Worker.SnapshotWorker do

SnapshotContext.update_snapshot(snapshot, %{
status: "failure",
data: Jason.encode!(reason: msg)
data: Jason.encode!(%{reason: msg})
})
end
end
Expand All @@ -73,7 +73,7 @@ defmodule Lynx.Worker.SnapshotWorker do
end

defp schedule_work do
# We schedule the work to happen in 60 seconds
Process.send_after(self(), :fire, 60 * 1000)
# We schedule the work to happen in 30 seconds
Process.send_after(self(), :fire, 30 * 1000)
end
end
26 changes: 24 additions & 2 deletions lib/lynx_web/controllers/snapshot_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ defmodule LynxWeb.SnapshotController do
@default_list_limit "10"
@default_list_offset "0"

plug :regular_user when action in [:list, :index, :create, :delete]
plug :access_check when action in [:index, :delete]
plug :regular_user when action in [:list, :index, :create, :delete, :restore]
plug :access_check when action in [:index, :delete, :restore]

defp regular_user(conn, _opts) do
Logger.info("Validate user permissions")
Expand Down Expand Up @@ -164,6 +164,28 @@ defmodule LynxWeb.SnapshotController do
end
end

@doc """
Restore Snapshot Endpoint
"""
def restore(conn, %{"uuid" => uuid}) do
case SnapshotModule.restore_snapshot_by_uuid(uuid) do
{:error, msg} ->
conn
|> put_status(:bad_request)
|> render("error.json", %{message: msg})

{:not_found, msg} ->
conn
|> put_status(:not_found)
|> render("error.json", %{message: msg})

{:ok, task} ->
conn
|> put_status(:accepted)
|> render("restore.json", %{task: task})
end
end

defp validate_create_request(params) do
title = ValidatorService.get_str(params["title"], "")
description = ValidatorService.get_str(params["description"], "")
Expand Down
1 change: 1 addition & 0 deletions lib/lynx_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ defmodule LynxWeb.Router do
post "/snapshot", SnapshotController, :create
get "/snapshot/:uuid", SnapshotController, :index
delete "/snapshot/:uuid", SnapshotController, :delete
post "/snapshot/restore/:uuid", SnapshotController, :restore

# Environment Endpoints
get "/project/:p_uuid/environment", EnvironmentController, :list
Expand Down
8 changes: 7 additions & 1 deletion lib/lynx_web/templates/page/snapshots.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
new_snapshot: '<%= gettext "Snapshot created successfully!" %>',
delete_snapshot_message: '<%= gettext "Snapshot deleted successfully!" %>',
delete_snapshot_alert: '<%= gettext "You are trying to delete a snapshot! are you sure?" %>',
delete_snapshot_endpoint: '<%= Routes.snapshot_path(@conn, :delete, "UUID") %>'
delete_snapshot_endpoint: '<%= Routes.snapshot_path(@conn, :delete, "UUID") %>',
restore_snapshot_endpoint: '<%= Routes.snapshot_path(@conn, :restore, "UUID") %>',
restore_snapshot_alert: '<%= gettext "You are trying to restore a snapshot! are you sure?" %>',
restore_snapshot_pending_message: '<%= gettext "Snapshot restore is in progress!" %>',
restore_snapshot_success_message: '<%= gettext "Snapshot restored successfully!" %>',
restore_snapshot_failed_message: '<%= gettext "Snapshot restore has failed!" %>',
task_status_endpoint: '<%= Routes.task_path(@conn, :index, "UUID") %>'
}
</script>

Expand Down
11 changes: 11 additions & 0 deletions lib/lynx_web/views/snapshot_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ defmodule LynxWeb.SnapshotView do
%{errorMessage: message}
end

# Render restore task
def render("restore.json", %{task: task}) do
%{
id: task.uuid,
status: task.status,
runAt: task.run_at,
createdAt: task.inserted_at,
updatedAt: task.updated_at
}
end

# Format snapshot
defp render_snapshot(snapshot) do
{_, team} = TeamModule.get_team_by_id(snapshot.team_id)
Expand Down
39 changes: 39 additions & 0 deletions priv/static/theme/app/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ function format_datetime(datetime) {
return formattedDate;
}

function snapshot_restore_followup(id) {
axios.get(i18n_globals.task_status_endpoint.replace("UUID", id))
.then((response) => {
if (response.status >= 200) {
show_notification(response.data.status);

if (response.data.status == 'success') {
show_notification(i18n_globals.restore_snapshot_success_message);
} else if (response.data.status === 'failure') {
show_notification(i18n_globals.restore_snapshot_failed_message);
} else {
show_notification(i18n_globals.restore_snapshot_pending_message);
setTimeout(() => { snapshot_restore_followup(id) }, 6000);
}
}
})
.catch((error) => {
// Show error
show_notification(error.response.data.errorMessage);
});
}

// Install Page
lynx_app.install_screen = (Vue, axios, $) => {

Expand Down Expand Up @@ -872,6 +894,23 @@ lynx_app.snapshots_list = (Vue, axios, $) => {
});
},

restoreSnapshotAction(id) {
if (confirm(i18n_globals.restore_snapshot_alert) != true) {
return;
}

axios.post(i18n_globals.restore_snapshot_endpoint.replace("UUID", id), {})
.then((response) => {
if (response.status >= 200) {
show_notification(i18n_globals.restore_snapshot_pending_message);
snapshot_restore_followup(response.data.id);
}
})
.catch((error) => {
show_notification(error.response.data.errorMessage);
});
},

loadDataAction() {
var offset = (this.currentPage - 1) * this.limit;

Expand Down

0 comments on commit 6e0aeb5

Please sign in to comment.