Commit Graph

1825 Commits

Author SHA1 Message Date
yusing
15b9635ee1 fix(Makefile): exclude specific directories from gomod_paths search 2026-02-01 00:22:00 +08:00
yusing
33d512f550 fix(api): prevent timeout during agent verification
Send early HTTP 100 Continue response before processing to avoid
timeouts, and propagate request context through the verification flow
for proper cancellation handling.
2026-02-01 00:22:00 +08:00
yusing
c7a70f630a fix(autocert): rebuild SNI matcher after ObtainCertAll operations
The ObtainCertAll method was missing a call to rebuildSNIMatcher(),
which could leave the SNI configuration stale after certificate
renewals. Both ObtainCertIfNotExistsAll and ObtainCertAll now
consistently rebuild the SNI matcher after their operations.

This was introduced in 3ad6e98a17,
not a bug fix for previous version
2026-02-01 00:22:00 +08:00
yusing
12a8b9a1b4 feat(route): add YAML anchor exclusion reason
Add ExcludedReasonYAMLAnchor to explicitly identify routes with "x-" prefix
used for YAML anchors and references. These routes are removed before
validation.
2026-02-01 00:22:00 +08:00
yusing
4c62a4b365 fix(route): allow excluded routes to use localhost addresses
Routes marked for exclusion should bypass normal validation checks,
including the restriction on localhost/127.0.0.1 hostnames.
2026-02-01 00:22:00 +08:00
yusing
5c30f4a859 fix(health/check): validate URL port before dialing in Stream check
Add port validation to return an unhealthy result with descriptive
message when URL has no port specified, preventing potential dialing
errors on zero port.
2026-02-01 00:22:00 +08:00
yusing
c6e4e83fcd chore: disable godoxy health checking for socket-proxy 2026-02-01 00:22:00 +08:00
yusing
c54741aab6 feat(autocert): generate unique ACME key paths per CA directory URL
Previously, ACME keys were stored at a single default path regardless of
which CA directory URL was configured. This caused key conflicts when
using multiple different ACME CAs.

Now, the key path is derived from a SHA256 hash of the CA directory URL,
allowing each CA to have its own key file:
- Default CA (Let's Encrypt): certs/acme.key
- Custom CA: certs/acme_<url_hash_16chars>.key

This enables running certificates against multiple ACME providers without
key collision issues.
2026-02-01 00:21:59 +08:00
yusing
fb6b692f55 fix(autocert): correct ObtainCert error handling
- ObtainCertIfNotExistsAll longer fail on fs.ErrNotExists
- Separate public LoadCertAll (loads all providers) from private loadCert
- LoadCertAll now uses allProviders() for iteration
- Updated tests to use LoadCertAll
2026-02-01 00:21:59 +08:00
yusing
1319f72805 refactor: propagate context and standardize HTTP client timeouts
Add context parameter to TCP/UDP stream health checks and client constructors
for proper cancellation and deadline propagation. Switch from encoding/json
to sonic for faster JSON unmarshaling.

Standardize HTTP client timeouts to 5 seconds
across agent pool and health check.
2026-02-01 00:21:50 +08:00
yusing
52511f1618 Cherry-pick 372132b1da 2026-01-30 00:33:34 +08:00
yusing
ca2cbd3332 chore: upgrade dependencies 2026-01-30 00:32:39 +08:00
yusing
57f7b72923 chore(json): use stdlib json for compatibility 2026-01-30 00:30:48 +08:00
yusing
54b3008cce refactor: propagate context and standardize HTTP client timeouts
Add context parameter to TCP/UDP stream health checks and client constructors
for proper cancellation and deadline propagation. Switch from encoding/json
to sonic for faster JSON unmarshaling.

Standardize HTTP client timeouts to 5 seconds
across agent pool and health check.
2026-01-30 00:28:17 +08:00
yusing
d9abd65471 factor(route): make proxmox validation non-critical
Proxmox validation errors are now logged and ignored rather than
causing route validation to fail, allowing routes to function even
when proxmox integration encounters issues.

- Extract proxmox validation into dedicated validateProxmox() method
- Log warnings/errors instead of returning validation errors
- Add warning when proxmox config exists but no node/resource found
2026-01-30 00:28:00 +08:00
yusing
d5b9d2e6bc fix(serialization): correct validation parameter
- Fix bug in mapUnmarshalValidate where checkValidateTag parameter
  was incorrectly negated when passed to Convert()
- Remove obsolete validateWithValidator helper function
2026-01-30 00:28:00 +08:00
yusing
ec9cab05c7 chore(docs): update package docs for internal/serialization 2026-01-30 00:27:59 +08:00
yusing
6ff1346675 feat(api): add route validation endpoint with WebSocket support
Adds a new `/route/validate` endpoint that accepts YAML-encoded route
configurations for validation. Supports both synchronous HTTP requests
and real-time streaming via WebSocket for interactive validation workflows.

Changes:
- Implement Validate handler with YAML binding in route/validate.go
- Add WebSocket manager for streaming validation results
- Register GET/POST routes in handler.go
- Regenerate Swagger documentation
2026-01-30 00:27:58 +08:00
yusing
a75441aa8a refactor(serialization): generalize unmarshal/load functions with pluggable format handlers
Replace YAML-specific functions with generic ones accepting unmarshaler/marshaler
function parameters. This enables future support for JSON and other formats
while maintaining current YAML behavior.

- UnmarshalValidateYAML -> UnmarshalValidate(unmarshalFunc)
- UnmarshalValidateYAMLXSync -> UnmarshalValidateXSync(unmarshalFunc)
- SaveJSON -> SaveFile(marshalFunc)
- LoadJSONIfExist -> LoadFileIfExist(unmarshalFunc)
- Add UnmarshalValidateReader for reader-based decoding

Testing: all 12 staged test files updated to use new API
2026-01-30 00:27:38 +08:00
yusing
32971b45c3 chore(swagger): update API documentation annotations
- Change ValidateFile endpoint Accept type from text/plain to json
- Add Route struct name annotation for Swagger documentation
2026-01-30 00:27:07 +08:00
yusing
4bc7ce09c7 chore(docs): update package docs for internal/proxmox 2026-01-30 00:27:06 +08:00
yusing
b5946b34b8 refactor(proxmox): add struct level validation for node configuration services and files
Add Validate() method to NodeConfig that implements the CustomValidator
interface. The method checks all services and files for invalid shell
metacharacters (&, $(), etc.) to prevent shell injection attacks.

Testing: Added validation_test.go with 6 table-driven test cases covering
valid inputs and various shell metacharacter injection attempts.
2026-01-30 00:26:59 +08:00
yusing
442e4a0972 fix(proxmox): improve journalctl with log tailing fallback for non-systemd systems
- Format tail command with fallback retry logic
- Add /var/log/messages fallback when no services specified

Improves log viewing reliability on systems without systemd support.
2026-01-30 00:26:28 +08:00
yusing
d1c79acf87 fix(docker): improve error handling for missing Docker agent
Replaced panic with an error return in the NewClient
2026-01-28 17:23:53 +08:00
yusing
df70f7f63c refactor(proxmox): add validation for node name and VMID in provider initialization 2026-01-28 17:23:52 +08:00
yusing
6707143aaf refactor(logging): add non-blocking writer for high-volume logging
Replace synchronous log writing with zerolog's diode-based non-blocking
writer to prevent logging from blocking the main application during
log bursts. The diode writer buffers up to 1024 messages and logs a
warning when messages are dropped.

- Extract multi-writer logic into separate `multiWriter` function
- Wrap with `diode.NewWriter` for async buffering
- Update both `NewLogger` and `NewLoggerWithFixedLevel` to use diode
2026-01-28 17:23:52 +08:00
yusing
742a86d079 refactor(config): simplify route provider loading with improved error handling
Streamlined the `loadRouteProviders()` function by:
- Replacing channel-based concurrency with a simpler sequential registration pattern after agent initialization
- Using `gperr.NewGroup` and `gperr.NewBuilder` for more idiomatic error handling
- Adding mutex protection for concurrent result building
- Removing the `storeProvider` helper method
2026-01-28 17:23:51 +08:00
yusing
45f856b8d1 chore(config): make initialization timeout configurable via environment variable
Replaced hardcoded 10-second initialization timeout with a configurable `INIT_TIMEOUT` environment variable.
The new default is 1 minute, allowing operators to adjust startup behavior based on their infrastructure requirements.
2026-01-28 17:23:51 +08:00
yusing
044c7bf8a0 feat(proxmox): add session refresh loop to maintain Proxmox API session
Introduced a new session refresh mechanism in the Proxmox configuration to ensure the API session remains active. This includes:
- Added `SessionRefreshInterval` constant for configurable session refresh timing.
- Implemented `refreshSessionLoop` method to periodically refresh the session and handle errors with exponential backoff.

This enhancement improves the reliability of interactions with the Proxmox API by preventing session expiry.
2026-01-28 17:23:50 +08:00
yusing
e7b19c472b feat(proxmox): add tail endpoint and enhance journalctl with multi-service support
Add new `/proxmox/tail` API endpoint for streaming file contents from Proxmox
nodes and LXC containers via WebSocket. Extend journalctl endpoint to support
filtering by multiple services simultaneously.

Changes:
- Add `GET /proxmox/tail` endpoint supporting node-level and LXC container file tailing
- Change `service` parameter from string to array in journalctl endpoints
- Add input validation (`checkValidInput`) to prevent command injection
- Refactor command formatting with proper shell quoting

Security: All command inputs are validated for dangerous characters before
2026-01-28 17:23:45 +08:00
yusing
1ace5e641d feat(proxmox): better node-level routes auto-discovery with pointer VMID
- Add BaseURL field to Client for node-level route configuration
- Change VMID from int to *int to support three states:
  - nil: auto-discover node or VM from hostname/IP/alias
  - 0: node-level route (direct to Proxmox node API)
  - >0: LXC/QEMU resource route with container control
- Change Service string to Services []string for multi-service support
- Implement proper node-level route handling: HTTPS scheme,
  hostname from node BaseURL, default port 8006
- Move initial UpdateResources call to Init before starting loop
- Move proxmox auto-discovery earlier in route validation

BREAKING: NodeConfig.VMID is now a pointer type; NodeConfig.Service
renamed to Services (backward compatible via alias)
2026-01-28 17:23:29 +08:00
yusing
83976646db feat(api): support query parameters for proxmox journalctl endpoint
Refactored the journalctl API to accept `node`, `vmid`, and `service` parameters as query strings in addition to path parameters. Added a new route `/proxmox/journalctl` that accepts all parameters via query string while maintaining backward compatibility with existing path-parameter routes.

- Changed `JournalctlRequest` struct binding from URI-only to query+URI
- Simplified Swagger documentation by consolidating multiple route definitions
- Existing path-parameter routes remain functional for backward compatibility
2026-01-28 17:23:29 +08:00
yusing
8e1d75abd6 refactor(swagger): rename DockerConfig and ProxmoxNodeConfig to IdlewatcherDockerConfig and IdlewatcherProxmoxNodeConfig 2026-01-28 17:23:28 +08:00
yusing
5c341d4745 refactor: improve error handling, validation and proper cleanup 2026-01-28 17:23:28 +08:00
yusing
9f245a62f2 fix(proxmox): concurrent map write in UpdateResources 2026-01-25 18:05:36 +08:00
yusing
ecc2547eb1 chore: go mod tidy 2026-01-25 17:41:10 +08:00
yusing
e2a48fcff9 fix(api/docker): correct paramaters 2026-01-25 17:40:47 +08:00
yusing
6b09f54793 chore: upgrade dependencies 2026-01-25 17:31:29 +08:00
yusing
7b5ad3ab5e chore(docker): add go-proxmox module dependencies to Dockerfile 2026-01-25 17:30:23 +08:00
yusing
48790b4756 refactor(types): decouple Proxmox config from proxmox package
Decouple the types package from the internal/proxmox package by defining
a standalone ProxmoxConfig struct. This reduces circular dependencies
and allows the types package to define its own configuration structures
without importing the proxmox package.

The route validation logic now converts between types.ProxmoxConfig and
proxmox.NodeConfig where needed for internal operations.
2026-01-25 17:29:43 +08:00
yusing
727a3e9452 chore(docs): enhance README with Proxmox integration details
Added sections for Proxmox integration, including automatic route binding, WebUI management, and API endpoints. Updated existing content to reflect LXC lifecycle control and real-time logging capabilities for both Docker and Proxmox environments.
2026-01-25 17:29:42 +08:00
yusing
f8f1b54aaf fix(scripts/update-wiki): add "internal/go-proxmox/" to skipSubmodules list 2026-01-25 17:29:42 +08:00
yusing
cb8f405e76 feat(proxmox): add node-level stats endpoint with streaming support
Add new `/proxmox/stats/{node}` API endpoint for retrieving Proxmox node
statistics in JSON format. The endpoint returns kernel version, CPU
usage/model, memory usage, rootfs usage, uptime, and load averages.

The existing `/proxmox/stats/{node}/{vmid}` endpoint has been corrected `VMStats` to return`text/plain` instead of `application/json`.

Both endpoints support WebSocket streaming for real-time stats updates
with a 1-second poll interval.
2026-01-25 17:29:41 +08:00
yusing
51704829c6 refactor(proxmox): move NodeCommand to node_command.go 2026-01-25 17:29:36 +08:00
yusing
a1cc1d844d chore(docs): update package docs for proxmox and route/routes 2026-01-25 17:29:01 +08:00
yusing
633deb85ca feat(proxmox): support node-level routes and journalctl access
This change enables Proxmox node-level operations without requiring a specific
LXC container VMID.

**Features added:**
- New `/proxmox/journalctl/{node}` API endpoint for streaming node journalctl
- Route configuration support for Proxmox nodes (VMID = 0)
- `ReverseLookupNode` function for node discovery by hostname/IP/alias
- `NodeJournalctl` method for executing journalctl on nodes

**Behavior changes:**
- VMID parameter in journalctl endpoints is now optional
- Routes targeting nodes (without specific containers) are now valid

**Bug fixes:**
- Fixed error message variable reference in route validation
2026-01-25 17:29:00 +08:00
yusing
ee1c375fd9 refactor(proxmox): extract websocket command execution into reusable NodeCommand method
The LXCCommand method contained duplicate websocket handling logic for connecting to Proxmox's VNC terminal proxy. This refactoring extracts the common websocket connection, streaming, and cleanup logic into a new NodeCommand method on the Node type, allowing LXCCommand to simply format the pct command and delegate.

The go-proxmox submodule was also updated to access the NewNode constructor, which provides a cleaner API for creating node instances with the HTTP client.

- Moves ~100 lines of websocket handling from lxc_command.go to node.go
- Adds reusable NodeCommand method for executing commands via VNC websocket
- LXCCommand now simply calls NodeCommand with formatted command
- Maintains identical behavior and output streaming semantics
2026-01-25 17:28:58 +08:00
yusing
2713f5282e fix(proxmox): prevent goroutine leaks by closing idle HTTP connections
Added a function to close idle HTTP connections in the LXCCommand method. This addresses potential goroutine leaks caused by the go-proxmox library's TermWebSocket not closing underlying HTTP/2 connections. The websocket closer is now wrapped to ensure proper cleanup of transport connections when the command execution is finished.
2026-01-25 17:28:17 +08:00
yusing
f70cca0d00 fix(swagger): remove /api/v1 prefix from Proxmox endpoints
Streamline Proxmox API route paths by removing incorrect /api/v1 prefix.

Changed endpoints:
- /api/v1/proxmox/journalctl/{node}/{vmid} → /proxmox/journalctl/{node}/{vmid}
- /api/v1/proxmox/journalctl/{node}/{vmid}/{service} → /proxmox/journalctl/{node}/{vmid}/{service}
- /api/v1/proxmox/lxc/:node/:vmid/restart → /proxmox/lxc/:node/:vmid/restart
- /api/v1/proxmox/lxc/:node/:vmid/start → /proxmox/lxc/:node/:vmid/start
- /api/v1/proxmox/lxc/:node/:vmid/stop → /proxmox/lxc/:node/:vmid/stop
- /api/v1/proxmox/stats/{node}/{vmid} → /proxmox/stats/{node}/{vmid}

Updated:
- Swagger annotations in 5 Go source files
- Generated swagger.json and swagger.yaml documentation
2026-01-25 17:28:16 +08:00
yusing
3adefe4202 fix: add startup timeout guard to prevent indefinite hangs
Add a 10-second timeout mechanism during application initialization. If initialization
fails to complete within the timeout window, the application logs a fatal error and exits.
This prevents the proxy from becoming unresponsive during startup due to blocking operations
in parallel initialization tasks (DNS providers, icon cache, system info poller, middleware
loading, Docker client, API server, debug server, config watcher).

The timeout guard uses a background goroutine that listens for either a completion signal
(via closing the done channel) or the timeout expiration, providing a safety net for
long-running or blocked initialization scenarios.
2026-01-25 17:28:15 +08:00