-
Notifications
You must be signed in to change notification settings - Fork 0
feat: surface alignment + memory persistence + progressive delivery #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
924b9ee
ed51905
538f17e
9ed2280
3d0ea1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,31 +39,65 @@ defmodule Nopea.API.Router do | |
| handle_deploy(conn) | ||
| end | ||
|
|
||
| get "/api/status/:service" do | ||
| case Nopea.Surface.status(service) do | ||
| {:ok, state} -> json(conn, 200, state) | ||
| {:error, :not_found} -> json(conn, 404, %{error: "not_found"}) | ||
| {:error, :unavailable} -> json(conn, 503, %{error: "unavailable"}) | ||
| end | ||
| end | ||
|
|
||
| get "/api/context/:service" do | ||
| namespace = conn.params["namespace"] || "default" | ||
|
|
||
| context = | ||
| if Process.whereis(Nopea.Memory) do | ||
| Nopea.Memory.get_deploy_context(service, namespace) | ||
| else | ||
| %{known: false} | ||
| end | ||
|
|
||
| context = Nopea.Surface.context(service, namespace) | ||
| json(conn, 200, context) | ||
| end | ||
|
|
||
| get "/api/history/:service" do | ||
| history = | ||
| if Nopea.Cache.available?() do | ||
| case Nopea.Cache.get_service_state(service) do | ||
| {:ok, state} -> %{service: service, state: state} | ||
| {:error, :not_found} -> %{service: service, deployments: []} | ||
| end | ||
| else | ||
| %{service: service, deployments: []} | ||
| end | ||
|
|
||
| json(conn, 200, history) | ||
| case Nopea.Surface.history(service) do | ||
| {:ok, data} -> json(conn, 200, data) | ||
| {:error, :not_found} -> json(conn, 200, %{service: service, deployments: []}) | ||
| {:error, :unavailable} -> json(conn, 200, %{service: service, deployments: []}) | ||
| end | ||
| end | ||
|
|
||
| get "/api/explain/:service" do | ||
| namespace = conn.params["namespace"] || "default" | ||
| explanation = Nopea.Surface.explain(service, namespace) | ||
| json(conn, 200, %{service: service, explanation: explanation}) | ||
| end | ||
|
|
||
| get "/api/services" do | ||
| services = Nopea.Surface.services() | ||
| json(conn, 200, %{services: services, count: length(services)}) | ||
| end | ||
|
|
||
| post "/api/promote/:deploy_id" do | ||
| case Nopea.Surface.promote(deploy_id) do | ||
| {:ok, rollout} -> | ||
| json(conn, 200, Map.from_struct(rollout)) | ||
|
|
||
| {:error, :not_found} -> | ||
| json(conn, 404, %{error: "not_found"}) | ||
|
|
||
| {:error, reason} -> | ||
| Logger.error("Promote failed", deploy_id: deploy_id, error: inspect(reason)) | ||
| json(conn, 500, %{error: "Internal server error"}) | ||
| end | ||
| end | ||
|
|
||
| post "/api/rollback/:deploy_id" do | ||
| case Nopea.Surface.rollback(deploy_id) do | ||
| {:ok, rollout} -> | ||
| json(conn, 200, Map.from_struct(rollout)) | ||
|
|
||
| {:error, :not_found} -> | ||
| json(conn, 404, %{error: "not_found"}) | ||
|
|
||
| {:error, reason} -> | ||
| Logger.error("Rollback failed", deploy_id: deploy_id, error: inspect(reason)) | ||
| json(conn, 500, %{error: "Internal server error"}) | ||
| end | ||
|
Comment on lines
+75
to
+100
|
||
| end | ||
|
|
||
| match _ do | ||
|
|
@@ -80,7 +114,7 @@ defmodule Nopea.API.Router do | |
| strategy: Nopea.Helpers.parse_strategy(params["strategy"]) | ||
| } | ||
|
|
||
| result = Nopea.Deploy.run(spec) | ||
| result = Nopea.Deploy.deploy(spec) | ||
| json(conn, 200, Nopea.Helpers.serialize_deploy_result(result)) | ||
|
|
||
| _ -> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These endpoints return
500withinspect(reason)in the JSON body. This can leak internal details (atoms, exception messages, potentially upstream responses) to API clients.Prefer logging
reasonserver-side and returning a stable, client-safe error payload (similar tohandle_deploy/1’sInternal server error).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 3d0ea1e — error responses now return a generic
"Internal server error"message. The actual reason is logged server-side viaLogger.errorwith the deploy_id for correlation.