Skip to content

PR26.7: Plesk adapter via conf.d/panel_loader (panelfw)#534

Merged
itcmsgr merged 2 commits intomainfrom
feat/pr26.7-plesk-adapter
Apr 30, 2026
Merged

PR26.7: Plesk adapter via conf.d/panel_loader (panelfw)#534
itcmsgr merged 2 commits intomainfrom
feat/pr26.7-plesk-adapter

Conversation

@itcmsgr
Copy link
Copy Markdown
Owner

@itcmsgr itcmsgr commented Apr 30, 2026

Summary

Second adapter under the PR26.2 panelfw contract, mirroring the PR26.3+PR26.4 DirectAdmin shape. Plesk-first sequence (cPanel deferred to PR26.8 because the cPanel host is currently down/incident-tied; clean Plesk path is available).

  • Adapter (`internal/installer/panelfw/adapters/plesk/plesk.go`): Detect via 4 signals (`/usr/local/psa`, `httpdmng` marker, `plesk.service`, TCP 8443 listener). RequiredPorts loads canonical `etc/nftban/conf.d/panels/plesk/main.conf` via `internal/ports/panel_loader.LoadPanelConfig("plesk")`. ValidateReachability probes TCP 8443 only (the HTTPS control plane).
  • Tests (`plesk_test.go`): 25 tests covering Detect, RequiredPorts (incl. real-loader against shipped conf.d, fail-closed, defensive copy, FUTURE-AUDITOR DIRECTIVE block), ValidateReachability (incl. 8447-not-8443 guard), framework integration, init registration, read-only discipline.
  • Wiring (`cmd/nftban-installer/main.go`): blank-import alongside DirectAdmin.

Differences from DirectAdmin

  1. No per-host control-port override. Plesk has no canonical config file analogous to `directadmin.conf` `port=N`. The adapter returns the constant default 8443. Seam for future override is at the same place as DA's `readConfiguredPort`.
  2. TCP 8447 is not control-plane. It's part of the conf.d full surface (Plesk Updater) but may be closed on a healthy panel host. Dedicated test guards against the adapter "passing" a Plesk host where only 8447 listens.

Test plan

  • `go vet ./internal/installer/panelfw/... ./cmd/nftban-installer/...` — clean
  • `go test -v ./internal/installer/panelfw/adapters/plesk/...` — 25/25 PASS on lab2
  • `go test ./internal/installer/... ./cmd/nftban-installer/...` — 18/18 packages PASS on lab2 (no DA regression)
  • `go build ./cmd/nftban-installer` — builds clean with both adapters
  • CI green
  • Auditor review
  • Real-host Plesk evidence — deferred until PR26.7 merged + Tier 1 rebuilt + clean non-build Plesk host authorized (lab2 is the build host; using it destructively would weaken isolation)

Out of scope

  • cPanel adapter (PR26.8 — gated on Plesk evidence + clean cPanel host)
  • DirectAdmin changes
  • Shell decommission of `nftban_panel_plesk.sh`
  • Plesk Firewall extension conflict detection (informational warn — future PR)
  • Plesk takeover lifecycle (no equivalent of `da build set csf no`)
  • Restore redesign
  • Destructive lab2/dns2/Plesk install

🤖 Generated with Claude Code

Second adapter under the PR26.2 panelfw contract, mirroring the
PR26.3+PR26.4 DirectAdmin shape. Plesk-first sequence (cPanel
deferred to PR26.8 because the cPanel host is currently down /
incident-tied; clean Plesk path is available).

ADAPTER

  internal/installer/panelfw/adapters/plesk/plesk.go

Detection (4 signals → strong/weak/absent):
  E1  /usr/local/psa                         (canonical install dir)
  E2  /usr/local/psa/admin/bin/httpdmng      (panel binary marker —
                                              from conf.d MARKER_BIN)
  E3  plesk.service active                   (systemd-managed run)
  E4  TCP 8443 in LISTEN state               (control plane serving)

Required ports:
  RequiredPorts() loads the canonical conf.d-declared TCP_IN / UDP_IN
  surface via internal/ports/panel_loader.LoadPanelConfig("plesk").
  Conf.d is the single source of truth; the adapter does NOT invent
  port lists. Fail-closed on missing/empty/nil.

Validate reachability:
  ValidateReachability() probes TCP 8443 ONLY (the Plesk HTTPS
  control plane). 8447 (Plesk Updater) is in the conf.d full surface
  but is NOT control-plane and may be closed on a healthy host.

Differences from DirectAdmin:
  - No per-host control-port override. Plesk has no canonical config
    file analogous to /usr/local/directadmin/conf/directadmin.conf
    `port=N`. The adapter returns the constant default 8443. If a
    future Plesk version exposes an override, the seam to add it is
    here (mirror DA's readConfiguredPort).
  - 8447 is intentionally part of the conf.d surface but not the
    control plane. A dedicated test guards against the adapter
    "passing" a Plesk host where only 8447 listens.

TESTS

  internal/installer/panelfw/adapters/plesk/plesk_test.go

  - 5 Detect tests (incl. negative-coupling guard: a DirectAdmin-shape
    mock must NOT trigger Plesk detection)
  - 11 RequiredPorts tests: stub-loader pass-through, fail-closed
    branches (missing/empty/nil), defensive copy, real-loader against
    shipped conf.d (no hardcoded port lists; structural assertions
    only — control-port presence, SSH absence, surface size floor).
    FUTURE-AUDITOR DIRECTIVE block included.
  - 6 ValidateReachability tests including the 8447-not-8443 guard.
  - 5 framework-integration tests (detected+reachable, detected+blocked,
    error-message scope discipline, absent host, --no-panel override).
  - init() registration verified.
  - Read-only discipline verified (no WrittenFiles, only ss + systemctl
    is-active commands recorded).

REGISTRATION

  cmd/nftban-installer/main.go

  Blank-import alongside DirectAdmin so init() registers the adapter
  before phaseValidate runs.

LAB PROOF (lab2, Ubuntu 24.04, go1.22.2):
  - go vet ./internal/installer/panelfw/... ./cmd/nftban-installer/...:
    clean
  - go test -count=1 -v ./internal/installer/panelfw/adapters/plesk/...:
    25 / 25 PASS
  - go test ./internal/installer/... ./cmd/nftban-installer/...:
    18 / 18 packages PASS (no regression in DirectAdmin or framework)
  - go build ./cmd/nftban-installer: builds clean with both adapters

OUT OF SCOPE
  - cPanel adapter (PR26.8 — gated on Plesk evidence + clean cPanel host)
  - DirectAdmin changes
  - Shell decommission of nftban_panel_plesk.sh
  - Plesk Firewall extension conflict detection (informational warn —
    future PR like PANEL-ENABLE-LEGACY-WARNING-001)
  - Plesk takeover lifecycle (no equivalent of `da build set csf no`
    yet wired here; Plesk uses systemd mask + Plesk-internal config)
  - Restore redesign
  - Real-host Plesk install evidence — gated on PR26.7 merge + green
    CI + Tier 1 rebuild + clean non-build Plesk host (lab2 is the
    build host; using it destructively would weaken isolation)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Auditor CONDITIONAL-GO blocker: error strings should not be capitalized
(staticcheck ST1005). Four error strings in plesk.go led with the
proper noun "Plesk", which staticcheck flags despite the capitalization
being correct English.

Behavior unchanged. Strings rephrased to keep "Plesk" capitalized
inside the message, just not at the leading position:

  - "Plesk conf.d load failed: ..."
    → "conf.d load failed for Plesk panel: ..."

  - "Plesk conf.d load returned nil PanelConfig"
    → "conf.d load returned nil PanelConfig for Plesk panel"

  - "Plesk conf.d declares no TCP_IN ports ..."
    → "conf.d for Plesk panel declares no TCP_IN ports ..."

  - "Plesk control-plane port %d not in LISTEN state ..."
    → "control-plane port %d (Plesk) not in LISTEN state ..."

One test (TestRequiredPorts_MissingConfD_FailsClosed) asserted
strings.Contains(err, "Plesk conf.d") — that exact substring no
longer appears. Adjusted to assert the error references both
"Plesk" and "conf.d" independently, preserving the test's intent
without weakening it.

Lab proof on lab2 (Ubuntu 24.04, go1.22.2):
  - go vet ./internal/installer/panelfw/adapters/plesk/... ./cmd/nftban-installer/...: clean
  - go test -v ./internal/installer/panelfw/adapters/plesk/...: 25/25 PASS
  - go test ./internal/installer/... ./cmd/nftban-installer/...: 18/18 packages PASS
  - staticcheck ./internal/installer/panelfw/adapters/plesk/...: exit 0 (ST1005 cleared)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@itcmsgr itcmsgr merged commit 867f047 into main Apr 30, 2026
63 checks passed
@itcmsgr itcmsgr deleted the feat/pr26.7-plesk-adapter branch April 30, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant