Commit Graph

1882 Commits

Author SHA1 Message Date
agent_coder bb68acfbf6 fix(#29 review r1): stack-delete leak, rollback/retention/version tests, UX trap
F3: deleting a file-based stack now removes the stack ROOT (compose/{id}) via a
new removeStackProjectDir helper, not stack.ProjectPath (which the PR repointed to
compose/{id}/v{N}) — old version dirs + parent no longer leak. Git stacks unchanged.
F1: tests for validateRollbackTarget (rejects 0/neg/>current/hole) and the rollback
snapshot (client content ignored, target read from disk, monotonic new version, note).
F2: tests for pruneStackFileVersionDirs (deletes given dirs, swallows errors) + the
post-commit gate contract + a monotonic-version regression guard.
F4: handler tests for ?version= (negative/out-of-range -> 400, valid version served,
legacy fallback).
F5: swagger @param version on GET file; @version 2.44.0 (handler.go) + package.json
2.44.0, matching APIVersion.
F6: the version selector no longer sets rollbackTo for the current/top version and
clears it on a manual buffer edit (so edits are honored, not silently discarded);
returning to the current version restores the current content. Distinguishes real
user edits from the programmatic version-load (CodeMirror ExternalChange).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 17:28:52 +03:00
agent_coder d0d3c068ba feat(stacks): file-based stack versioning with full history + rollback (#27)
Adds append-only version history on disk (compose/{id}/v{N}/<files>) for
file-based (WorkflowID==0) Compose/Swarm stacks, with rollback to any past
version. Git stacks (versioned by commit) and Kubernetes are untouched.

Backend:
- Stack model: StackFileVersion, PreviousDeploymentInfo, Versions[]; new
  StackFileVersionInfo type. APIVersion 2.43.0 -> 2.44.0.
- Versioned multi-file snapshot (entrypoint + AdditionalFiles) into v{N}/;
  ProjectPath repointed via GetStackProjectPathByVersion each deploy. Retention
  cap (20): Versions[] trimmed in-tx, old dirs deleted only AFTER the tx commits.
- Update handlers: RollbackTo (content read server-side from the target version,
  never trusted from the client; validated 1..current & present in Versions).
- Create paths seed v1. stackFile reads ?version= (validated; negative -> 400).
- New GET /stacks/{id}/versions endpoint.
- Migration 2.44.0: move existing file-based stacks' files into v1/ (idempotent,
  atomic pre-read of the full file set, skips git/kube/orphans).

Frontend:
- useStackVersions query + stackVersions key; StackEditorTab builds the full
  history list; StackVersionSelector shows 'v{N} · date · author'; file/versions
  caches invalidated (by prefix) after deploy/rollback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 16:07:26 +03:00
agent_coder 32f1b601b6 test(automation): fake-docker seam + daemon orchestration tests (closes #20)
The auto-update/auto-heal daemon apply paths (recreate/pull/rollback/cleanup/
heal-restart) mutate production containers but had no executing tests because
they took a concrete *dockerclient.Client. Introduce minimal seam interfaces
(dockerClient + containerRecreator) and thread them through updateStandalone/
cleanupOldImage/updateStack/inspectImageID/healthGate/rollback, extract the heal
restart loop into healContainers — all behaviour-preserving (the concrete client
and ContainerService satisfy the interfaces). Add a call-recording fake and
ordering/gating integration tests: cleanup runs strictly AFTER a healthy
health-gate (rollback target never deleted early), rollback fires on gate
failure and preserves the target, the 'updated' event is held until health is
confirmed, and the heal restart respects its cooldown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 23:46:09 +03:00
vvzvlad 594312a777 Merge pull request 'feat(automation): native container auto-update (Watchtower-style) + auto-heal (#3)' (#19) from feat/3-auto-update into develop
Reviewed-on: #19
2026-07-01 23:25:24 +03:00
agent_coder 492d3d01b0 feat(#19): separate webhook per automation mechanism (update vs heal)
Split the single container-automation webhook URL into two independently
optional URLs — UpdateWebhookURL (fired on update/rollback/update-failed) and
HealWebhookURL (fired on auto-heal restart). The notifier routes each event to
its mechanism's URL by kind; an empty URL silences only that mechanism, so a
user can enable notifications for updates without heal (or vice-versa).

Settings gain both fields (each validated http/https, {{message}} allowed), the
NotificationPanel exposes two labeled inputs, and the golden migration output is
updated. Delivery path (goroutine/recover/timeout, {{message}} GET vs POST,
per-container stack message format) is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:47:25 +03:00
agent_coder 5bb678d3ba fix(#19): address review F1-F4 (badge test, force write-back test, force throttle, per-container stack notifications)
- F1: test that clicking the badge/UpdateNowButton actually dispatches the update
  (confirm->mutate) for standalone and stack, and not on dismiss.
- F2: Go test that a successful forced re-check repopulates the caches (a later
  non-force read hits cache, no second registry HEAD).
- F3: throttle forced image-status re-checks against registry amplification —
  coalesce concurrent forced re-checks of the same image via singleflight, plus a
  5s per-image min-interval (== remoteDigestCache TTL) caching only successes. The
  non-force path (daemon + background badges) is unchanged.
- F4: notifications are now per-container. Stack-member containers each emit their
  own EventUpdated (not one aggregate stack event), Event carries the stack name
  (from the com.docker.compose.project label), and the new image digest is fetched
  best-effort by re-inspecting the container after the redeploy. Message:
  'Environment | .. / Stack [<name>] / Update [<container>]: <old> -> <new>'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 20:50:55 +03:00
agent_coder eb35e9c47f feat(automation): configurable webhook notifier for automation events
Add an opt-in webhook notification for container-automation events (image
update, rollback, update-failed, auto-heal restart), plugging into the existing
Notifier seam in notify.go.

- Settings: new ContainerAutomation.Notification.WebhookURL (shared across
  update + heal), persisted and validated in the settings update handler
  (optional; http/https only; accepts the {{message}} placeholder).
- webhookNotifier reads the current URL from the datastore per event (UI changes
  take effect without a restart). If the URL contains {{message}} it substitutes
  the URL-encoded message and issues a GET; otherwise it POSTs the message as the
  body. Delivery, the env/stack name lookups, and any panic run in a goroutine
  under recover() with a 10s timeout — strictly best-effort, never blocks or
  crashes the automation daemon. multiNotifier fans events to logNotifier +
  webhook and isolates a panic in any one notifier.
- Message format (maintainer's spec):
    Environment | <env>
    Stack [<name>]            (Container [<name>] for non-stack events)
    Update [<name>]: <old> -> <new>
  Auto-heal: 'Auto-heal: restarted unhealthy container'.
- New NotificationPanel in settings to configure the URL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:31:18 +03:00
agent_coder 6aecdfbe46 feat(containers): interactive image-status badge (click to update / re-check)
Make the container image-status badge actionable, matching native Portainer:
- Clicking "Update available" opens the update confirm dialog and runs the
  existing update flow (standalone recreate-with-pull / stack redeploy), gated
  and disabled while in flight to avoid a double submit. The confirm+apply logic
  is extracted from UpdateNowButton into a shared useApplyContainerImageUpdate
  hook so the details button and the list badge share one implementation.
- Clicking "Up to date" re-queries the registry. Because the server caches image
  status (statusCache 5m + remoteDigestCache 5s), a plain refetch was a no-op, so
  the endpoint gains an optional ?force=true that bypasses BOTH caches for a
  manual re-check while still repopulating them; the default (auto badges + the
  auto-update daemon) keeps using the caches unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 19:04:49 +03:00
claude code agent 7257ae52d8 test(logs): cover the docker proxy stream/flush loop (F1)
Extract the manual stream-and-flush loop from dockerLocalProxy.ServeHTTP
into a behaviour-preserving package-private streamResponse(w, body) helper,
and add docker_test.go regression tests for the riskiest path (it runs on
every Docker API response):

- DeliversFullBodyAndFlushesPerChunk: a >32KB body delivered as several
  chunks (boundaries not aligned to the 32KB buffer), with the final Read
  returning (n>0, io.EOF) simultaneously, asserts the streamed body equals
  the input exactly (no loss/duplication) and that Flush ran more than once
  (the per-chunk flush is the whole point of the change).
- StopsOnWriteErrorWithoutPanic: a writer that errors on first Write (and
  does not implement http.Flusher, exercising the nil-flusher fallback)
  breaks the loop after one write without panicking.

No production behaviour change — the loop body is identical, only moved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 02:58:48 +03:00
claude code agent 637e96f236 fix(logs): flush docker proxy stream per chunk; trim log-viewer settings UI
Backend (the "logs arrive every ~5s / pipe clogged" bug):
- dockerLocalProxy.ServeHTTP streamed the docker socket response via
  io.Copy, which buffers ~2KB into the ResponseWriter and only flushes
  when full or on handler return. Low-throughput streaming endpoints
  (container logs follow=1, events, stats, attach) therefore arrived in
  multi-second batches. Stream manually and Flush() after each chunk so
  they are delivered live. Behaviour is otherwise identical to io.Copy
  (full-write contract, EOF handling, Debug error logging); hijacked
  attach/exec go through a separate websocket handler, unaffected.
- NewSingleHostReverseProxyWithHostHeader: set FlushInterval = -1 so the
  remote-endpoint path streams live too.

Frontend (maintainer UI asks):
- Remove the line-selection mechanic entirely (Copy-selected-lines and
  Unselect buttons, selectLine/copySelection/clearSelection, selectedLines
  state, line_selected highlight): selecting/copying is mouse-native. Copy
  (all visible) and Download stay.
- Rename the unclear "Fetch" since-selector label to "Since".
- Move the settings controls into the widget header (rd-widget-header
  default transclude slot) so they share one row with the "Log viewer
  settings" title, reclaiming vertical space for the log pane.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 02:05:02 +03:00
claude code agent be3bfd0513 fix(automation): maintainer pre-merge review — stale detection, daemon edge cases, parity (F1-F9)
F1: cap the image-status cache TTL at 5m (was 24h) — the cache is keyed by the
    LOCAL imageID, which doesn't change when upstream pushes a new image under the
    same tag, so the 24h TTL hid new images from both the badge and the auto-update
    daemon; a short TTL re-resolves the remote digest within the poll window.
F2: document that the update->rollback guard map is in-memory (restart implication).
F3: skip auto-update for an unnamed container when rollback is on (the endpoint+name
    keyed guard can't record it, so it would loop) — pure skipUnnamedForRollback + test.
F4: wrap the pre-update ContainerInspect in context.WithTimeout(endpointTimeout).
F5: document Reload() does not interrupt an in-flight tick.
F6: floor auto-heal CheckInterval at 1s (mirrors auto-update) + test.
F7: wontfix — migration is currently correct; namespace rework is out of scope.
F8: correct the misleading SSRF/AllowList comment (no filter is applied).
F9: front auto-heal interval floor + test; dedup STALE_TIME; fix invalidation comment.
Also refresh three stale '24h/long-lived cache' comments to match the 5m TTL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:51:15 +03:00
claude code agent 6171806528 test(automation): cover pruneRolledBack boundary/retention (F8)
TestPruneRolledBack mirrors TestPruneRetries: seeds fresh/at-boundary/expired
rolledBack entries and asserts pruneRolledBack keeps only the fresh one
(inclusive >= cooldown boundary).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:06:49 +03:00
claude code agent 922f506fe5 feat(automation): guard update→rollback loop; name Settings types; tests & doc fixes (F1-F7)
F1: record rolled-back targets per service (endpointID/containerName + remote
    digest) and skip auto-update during a 24h cooldown unless the remote digest
    changes — breaks the infinite update→rollback loop on a persistently
    unhealthy image, without blocking a genuinely new image.
F2: unit-test applyContainerUpdate dispatch/payload mapping.
F3: settings_update.go comments mention auto-heal AND auto-update.
F4: drop stale '(future M4)' TS docs; primitives are frontend-only.
F5: replace the anonymous ContainerAutomation settings struct with named
    types (identical JSON tags).
F6: drop parseEnable (duplicate of boolLabel).
F7: remove the unused gitService dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:29:57 +03:00
claude code agent 70f7fe5e84 Merge remote-tracking branch 'origin/feat/10-update-now' into feat/3-auto-update 2026-06-29 12:48:24 +03:00
claude code agent cdf17d904d fix(automation): rollback robustness — transient inspect, start_period, digest images, shutdown, event order (#12 review)
F1: tolerate up to 3 consecutive health-gate inspect failures (reset on
success) before declaring an update failed, so a transient Docker API blip no
longer triggers a false rollback.

F2: detect baseCtx cancellation during the gate and abort without rolling back
or emitting update-failed (debug log only), instead of a misleading
"rollback failed" event on every shutdown mid-gate.

F3: derive the gate deadline as start + max(RollbackTimeout, StartPeriod+buffer)
via effectiveRollbackDeadline, reading the container's healthcheck StartPeriod
so a legitimately slow-starting container is not rolled back while starting.

F4: only enable the gate when the original reference is a proper tag (new
isTagReference helper); skip with a log line for digest-pinned / bare-image-id
containers that cannot be re-tagged.

F5: document the sequential-tick delay limitation of the gate poll.

F6: emit EventUpdated only after the gate confirms healthy (or immediately when
no gate is active); the rollback path emits only EventRollback, so the event
sequence is truthful.

F7: floor RollbackTimeout at 10s in backend and frontend validation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:57:54 +03:00
claude code agent 32a2b7a9ae feat(automation): health-gated rollback + per-endpoint + notify hook (#12, epic #3 M5)
P0 Health-gated rollback (standalone auto-update path): capture the previous
image id + reference + healthcheck before the recreate, then poll the new
container's health over a configurable window. On healthy proceed (and only
then clean up the old image); on unhealthy/exit/timeout re-tag the old image
back onto the original reference and Recreate (no pull) to restore it, reusing
Recreate's config preservation. The decision is a pure decideRollback() helper.

P1 Per-endpoint enable: ContainerAutomationDisabled flag on Endpoint (zero value
participates, no migration churn), checked by both daemons; settable via the
endpoint update API. UI control deferred (see report).

P2 Notifier seam: minimal Notifier interface + logNotifier, emitting structured
updated/rollback/update-failed/heal-restarted events from the daemon.

Settings: RollbackOnFailure + RollbackTimeout (default 120s) added to
ContainerAutomation.AutoUpdate, wired through defaults/migration/golden,
settings_update validation, the AutoUpdatePanel and the TS types.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:41:55 +03:00
claude code agent 21b5ec3e05 fix(automation): git-stack honesty + ECR registry refresh + interval floor (#11 review)
F1: Stop routing git-backed stacks through a per-tick RedeployWhenChanged for
image-only updates. The git redeploy path short-circuits when the commit is
unchanged (so an upstream-digest update never applies) yet still git-fetches
every tick. Git stacks are now detect-only in the auto-apply path; their image
update lands on the next git change or via manual "Update now". File (non-git)
stacks still force-pull-redeploy immediately. The AutoUpdatePanel text no longer
promises daemon auto-update for git/externally-managed containers.

F2: Resolve registries for the file-stack redeploy the same way the established
userless/system path (RedeployWhenChanged) does, via the new
deployments.ResolveStackRegistries: scope to the stack author's endpoint access
and RefreshAndPersistECRTokens, instead of hand-passing Registry().ReadAll().
ECR-backed stacks now auto-update with fresh tokens.

F3: Add a 1m floor for the auto-update poll interval, enforced in the settings
Validate and mirrored in the frontend validation.

F4: Thread the application shutdownCtx into NewService and use it as the base
for the heal/update job operation contexts, so shutdown cancels in-flight work.

F5: Correct the updateEndpoint comment about monitor-only badge-cache warming
(only in-scope monitor-only containers are status-checked).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:24:58 +03:00
claude code agent b3ae5f3659 feat(automation): native auto-update daemon (#11, epic #3 M4)
Add an optional periodic auto-update daemon that detects outdated container
images and applies updates, replacing the containrrr/watchtower sidecar. It
extends M1's containerautomation service/scheduler/labels infrastructure and
reuses the existing zlib image-detection engine, the standalone Recreate path
and the stack deployer.

Backend:
- api/containerautomation/autoupdate.go: scheduler job iterating Docker
  (non-edge) endpoints -> in-scope running containers -> ContainerImageStatus;
  for Outdated: standalone -> ContainerService.Recreate(pull); stack-managed ->
  one stack redeploy-with-pull per stack per tick (git via RedeployWhenChanged,
  file via the deployer directly); external compose -> detect only. Monitor-only
  containers are status-checked (warms the badge cache) but never applied.
  Overlap guard (atomic), pull/registry-auth failure -> leave running container
  untouched, conservative cleanup of the dangling old image on the Cleanup flag
  (non-forced ImageRemove only succeeds when truly unused).
- labels.go: update enable / monitor-only labels with watchtower aliases,
  InUpdateScope, IsMonitorOnly, and pure resolveContainerUpdateRouting /
  groupContainersForUpdate (Go analogue of M3's TS routing + grouping).
- service.go: run both jobs, Reload restarts/stops each per settings; NewService
  also takes ContainerService, StackDeployer and GitService.
- Settings.ContainerAutomation.AutoUpdate {Enabled, PollInterval, Scope,
  Cleanup} with fresh-install defaults and a 2.43.0 backfill (extends M1's
  migration; golden test data updated). settings handler validates + reloads.

Frontend:
- Global AutoUpdatePanel in SettingsView (enable / poll interval / scope /
  cleanup) via useUpdateSettingsMutation, plus settings TS types.
- Read-only per-container Auto-update row in the container details view
  (Docker labels are immutable at runtime), surfacing monitor-only.

Tests: Go unit tests for the update label aliases, scope, monitor-only, the
routing decision and the one-redeploy-per-stack grouping; vitest for the panel
and the per-container row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:04:09 +03:00
claude code agent 7eaff4dab0 fix(automation): real status cache read + nodeName key + honest errors (#9 review)
F1: ContainerImageStatus now reads the 24h statusCache (keyed by imageID)
before the remote registry digest lookup, so the cache is effective on the
input side for all callers instead of being write-only. This avoids the
rate-limited registry HEAD on repeat loads.

F2: add nodeName to the imageStatus query key so cached results cannot be
reused across nodes.

F3: correct the swagger annotations to reflect that engine-level issues
degrade to a 200 skipped/error status rather than 400/404.

F4: return a generic error message to the client instead of the raw
registry/engine error; the raw error is still logged server-side.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 09:09:18 +03:00
claude code agent f69eb3f9eb feat(automation): CE container image update detection endpoint + badge (#9, epic #3 M2)
Add native CE detection of "a newer image is available" for running
containers, surfaced as a read-only HTTP endpoint and a containers-list
badge/column. No applying of updates (M3/M4), no auto-heal (M1).

Backend:
- New CE handler GET /docker/{id}/containers/{containerId}/image_status
  backed by the existing zlib/CE digest engine
  (images.NewClientWithRegistry + ContainerImageStatus). Honors nodeName,
  authz, and routes registry calls through the credential store / SSRF
  AllowList. Engine failures degrade to a 200 {Status:"error"} so the UI
  stays graceful. Response shape: {Status, Message?}.

Frontend (CE-only, no isBE gating; the EE ImageStatus component is left
untouched):
- useContainerImageStatus TanStack Query hook (5min staleTime, no
  refetch-on-focus; backend caches 24h) calling the non-proxied endpoint.
- UpdateStatusBadge component (own assets, neutral on skipped/error).
- "Update available" column in the containers datatable; one cached,
  non-blocking query per visible row.

Tests: Go response-shape unit test; vitest for the badge (all statuses)
and the hook (url + nodeName query param via msw).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:59:54 +03:00
claude code agent b233f75ab7 fix(automation): retry-state retention + running-only heal + per-restart ctx (#8 F1-F6)
F1: prune retry-state by elapsed window since lastRestart instead of "not
seen this tick", so a container flapping through "starting" keeps its
cooldown/max-retries accounting (storm guard no longer defeated). Recovered
containers quiet for > window are still cleaned up.
F2: list running containers only (All:false) so stopped-unhealthy containers
are never revived.
F3: each ContainerRestart gets its own context (stop-timeout + buffer),
separate from the per-endpoint list context, so a slow/hung restart cannot
starve the others or exhaust a single shared deadline.
F4: start() is idempotent (no-op when a job is already scheduled); Reload
still stops first so it always reschedules.
F5: frontend parseBool mirrors Go strconv.ParseBool (case-insensitive
1/t/true; present-but-invalid counts as present & false).
F6: tests TestPruneRetries and TestRetryStateSurvivesStartingTick lock in
the F1 behavior; added AutoHealRow parse cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:39:17 +03:00
claude code agent 51957d2f98 feat(automation): native auto-heal daemon (#8, epic #3 M1)
Add a native, CE-only auto-heal daemon that restarts Docker containers whose
healthcheck reports "unhealthy", replacing the willfarrell/autoheal sidecar.

Backend:
- New package api/containerautomation (service lifecycle + scheduler job,
  per-endpoint heal pass, label/scope parsing, in-memory cooldown/retry state).
- Settings.ContainerAutomation.AutoHeal {Enabled, CheckInterval, Scope} with
  fresh-install defaults and a 2.43.0 migration backfilling existing installs.
- Settings update handler reloads/stops the job via a small Reloader interface
  (no import cycle); service bootstrapped from main.go after stack schedules.

Frontend:
- Global AutoHealPanel in SettingsView (enable / interval / scope) via
  useUpdateSettingsMutation, plus settings TS types.
- Read-only per-container Auto-heal row in the container details view (Docker
  labels are immutable at runtime; opt-in is set via Create/Edit form labels).

Tests: Go unit tests for label/scope resolution and the cooldown/retry decision;
vitest for the panel and the per-container row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:22:46 +03:00
andres-portainer e664bf0e19 fix(helm): add missing SSRF protections BE-13136 (#3001) 2026-06-22 20:25:10 -03:00
andres-portainer a6370808ae fix(ssrf): disable HTTP/2 for some specific cases BE-13121 (#2996) 2026-06-22 16:13:43 -03:00
Phil Calder f596c862b3 fix(websocket): enforce environment authorization on kubernetes-shell [BE-13027] (#2774)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: oscarzhou <oscar.zhou@portainer.io>
2026-06-22 15:09:41 +12:00
bernard-portainer 5395dee4c6 feat(gpu-stats): add gpu stats to environments [C9S-200] (#2735) 2026-06-22 09:21:43 +12:00
Josiah Clumont 217fe870ef fix(git): use ListContext instead of List when fetching remote refs [C9S-263] (#2939) 2026-06-22 08:30:20 +12:00
andres-portainer 26334e9088 feat(ssrf): add missing transport wrappings and more checks BE-13021 (#2968) 2026-06-19 20:26:03 -03:00
RHCowan 37bd8c06b5 fix(security): gate docker dashboard and edge async command routes [R8S-1057] (#2953) 2026-06-19 11:08:01 +12:00
andres-portainer c821a1c59f fix(git): avoid cloning to memory and bypassing symlinking restriction BE-13115 (#2961) 2026-06-18 16:21:09 -03:00
Dakota Walsh f5d0b3d849 feat(kubernetes): Gateway api client included in kubeclient [C9S-244] (#2884) 2026-06-18 14:37:42 +12:00
Chaim Lev-Ari 4d539a691d feat(custom-templates): reuse existing git sources in create/update [BE-13053] (#2925)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:45:35 +03:00
Chaim Lev-Ari ee8e73d7f9 feat(edge/stacks): use source ID for edge stack git creation [BE-13044] (#2926)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 17:33:19 +03:00
Chaim Lev-Ari d9673e33ec feat(helm): reuse existing git sources in Kubernetes Helm-from-git install [BE-13046] (#2900)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-15 22:01:31 +03:00
andres-portainer 16b5554f66 fix(customtemplates): add resource controls BE-13019 (#2897) 2026-06-15 14:59:07 -03:00
Chaim Lev-Ari fcdd6b4510 feat(stacks): use source id to create git stacks [BE-13043] (#2870)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:49:26 +03:00
Devon Steenberg 8b21dfc318 feat(ssrf): add ssrf allow list to settings [BE-13021] (#2858) 2026-06-12 15:16:06 +12:00
Steven Kang f87fec6d61 fix(omni): prevent partial cluster creation on Talos/Kubernetes mismatch [R8S-1058] (#2849)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 11:50:16 +12:00
andres-portainer 0da42c01b6 feat(gitcredential): remove GitCredential BE-12919 (#2838) 2026-06-11 18:53:24 -03:00
Cara Ryan f3f0ca8e21 fix(rbac): Filter get namespace by allowed namespace list [SEC-61] (#2743) 2026-06-11 15:51:32 +12:00
Xing ac3416c5a2 feat(policies): define ObservabilityK8s policy type with deploy-and-connect and connect-only modes [C9S-121] (#2706)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 15:09:33 +12:00
Steven Kang 1cd6017df6 fix(api): add endpoint authorization check to /api/kubernetes/{id}/* route - develop [R8S-1056] (#2829) 2026-06-11 09:49:50 +12:00
andres-portainer babb4ffb37 fix(nolint): remove unnecessary nolint directives BE-13074 (#2852) 2026-06-10 15:35:08 -03:00
LP B 0c2f07988a feat(app/sources): source create view (#2680)
Co-authored-by: Chaim Lev-Ari <chaim.lev-ari@portainer.io>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 21:34:46 +03:00
Ali d7a1d34be7 feat(policies): docker cleanup policy [c9s-87] (#2681) 2026-06-10 16:17:23 +12:00
andres-portainer 154c19403a fix(chisel): release a lock earlier to avoid a deadlock and clean stale tunnels immediately BE-13050 (#2815) 2026-06-09 10:41:05 -03:00
andres-portainer 1765e41fd4 feat(ssrf): implement an SSRF protection mechanism BE-13021 (#2818) 2026-06-09 00:41:42 -03:00
Oscar Zhou 5cdd0023d7 fix(registry): suppress ecr token pre-validation error with warning log [BE-13059] (#2827) 2026-06-09 10:58:50 +12:00
andres-portainer df7a4b5d6f feat(gitops): improve the data model BE-12919 (#2819) 2026-06-08 15:01:55 -03:00
Josiah Clumont e3e2a3b782 fix(environments): Environment Groups detail view environment breakdown regression [BE-13051] (#2828) 2026-06-08 16:03:32 +12:00