Commit Graph
100 Commits
Author SHA1 Message Date
lukaszraczyloandGitHub 407ae1842c Update go.mod and go.sum (#60) 2026-07-21 06:54:04 +01:00
lukaszraczyloandGitHub 89258e70bb Update go.mod and go.sum (#59) 2026-07-20 07:20:26 +01:00
lukaszraczyloandGitHub dc24fe5d88 Update go.mod and go.sum (#58) 2026-07-19 06:56:12 +01:00
lukaszraczyloandGitHub 99485450a6 Update go.mod and go.sum (#57) 2026-07-17 06:45:47 +01:00
lukaszraczyloandGitHub 233671730a Update go.mod and go.sum (#56) 2026-07-09 05:24:01 +01:00
lukaszraczyloandGitHub 0d1f8560c3 Update go.mod and go.sum (#55) 2026-07-08 05:07:35 +01:00
lukaszraczyloandGitHub 5f62ca3ed1 Update go.mod and go.sum (#54) 2026-07-07 05:25:53 +01:00
lukaszraczyloandGitHub c2528f7eec Update go.mod and go.sum (#53) 2026-06-30 05:31:08 +01:00
lukaszraczyloandGitHub a37574371f Update go.mod and go.sum (#52) 2026-06-29 05:37:13 +01:00
lukaszraczyloandGitHub 0bab59d97d Update go.mod and go.sum (#51) 2026-06-27 05:26:45 +01:00
lukaszraczyloandGitHub 7acac8e885 Update go.mod and go.sum (#50) 2026-06-26 05:34:24 +01:00
lukaszraczyloandGitHub 87ce85b07b Update go.mod and go.sum (#49) 2026-06-25 05:31:14 +01:00
lukaszraczylo d5125a0d62 Optimisation & fixes 2026-06-21 12:59:55 +01:00
lukaszraczylo ab65c2e17b docs: add Telemetry section linking to oss-telemetry opt-out docs
Discloses the single anonymous adoption ping sent on startup and points
users to the upstream README section for full opt-out instructions
instead of duplicating the table here.
2026-05-21 04:06:27 +01:00
lukaszraczylo cda8b4be47 feat: anonymous usage telemetry via oss-telemetry
Send a single fire-and-forget ping at startup to help track adoption
and version spread. No persistent identifiers are collected.

main() is wrapped via runMain() so deferred Wait drains in-flight pings
before os.Exit.

Opt out via any of:
  DO_NOT_TRACK=1
  OSS_TELEMETRY_DISABLED=1
  KPORTAL_DISABLE_TELEMETRY=1
2026-05-21 02:59:46 +01:00
lukaszraczylo 3f11219dc1 test: drain healthcheck goroutine + lock read in HealthCallback test
CI on Linux flagged a race in TestStartWorker_HealthCallback_StatusChange:
the test read ui.updates while the healthchecker's per-port goroutine
(spawned by Register at checker.go:164) was still running and could
fire UpdateStatus through notifyStatusChange.

The earlier mutex on MockStatusUpdater protected the writes; the read
side was unprotected, and the goroutine had not finished by the time
the test started ranging over the slice on slower runners.

Fix:
  - call healthChecker.Unregister(fwd.ID()) to drain the per-port
    goroutine before reading
  - hold ui.mu around the slice read for belt-and-suspenders happens-
    before, regardless of goroutine timing

Verified locally with go test -race -count=20 on the targeted test
and -count=3 on the full forward package.
2026-05-06 18:24:38 +01:00
lukaszraczylo 62483f9475 docs: sync website + README + wizard guide + changelog with new features
docs/index.html (kportal.raczylo.com):
  - Features grid gains Bulk Generate, Sensitive Header Redaction,
    Verified Installer cards; Headless card subtext clarified to
    'logs to stderr'.
  - Keybindings: 'a' -> 'n' for Add (matches real binding).
  - Quick Install card notes SHA-256 + optional cosign verification
    and DRY_RUN / SKIP_COSIGN env vars.
  - New Bulk Generate usage tile with --dry-run hint; Headless tile
    redirects stderr.
  - HTTP Traffic Logging card mentions automatic header redaction
    and the wizard 'h' toggle.

README.md:
  - install.sh note expanded with DRY_RUN/SKIP_COSIGN table.
  - HTTP Traffic Logging section gains 'Toggling per-forward
    logging', 'Header redaction', and 'Advanced configuration'
    examples.
  - Headless mode clarified to log to stderr (2>kportal.log).
  - Troubleshooting note on accepted context-name characters.

WIZARD_USAGE.md:
  - Add binding corrected from 'a' to 'n'; 'e' (edit) row added.
  - 'h' httpLog toggle and Tab focus switch documented.
  - New 'Edit Forward Wizard' section noting same-port allowed and
    advanced httpLog preserved.
  - Esc-cancels-delete behaviour clarified.

CHANGELOG.md: [Unreleased] populated with Added / Changed / Fixed
entries for this session's user-facing work, dated 2026-05-06.

.kportal.yaml example: inline 'httpLog: true' comment on one
forward as a usage hint.
2026-05-06 15:03:35 +01:00
lukaszraczylo 0c11838326 refactor(cmd): extract main() into testable run() + per-mode helpers
main() body is now os.Exit(run(ctx, args, stdin, stdout, stderr))
where ctx comes from signal.NotifyContext and IO is io.Reader/Writer
instead of os.Std*. run() parses flags via a fresh flag.NewFlagSet
(no more package-level flag.* globals) and dispatches to:

  runShowVersion(stdout)
  runCheckUpdate(stdout, stderr)
  runConvert(input, output, stdout, stderr)
  runHeadless(ctx, opts)
  runVerboseTable(ctx, opts)
  runInteractive(ctx, opts)

Helpers extracted: parseFlags, resolveConfigPath, initLoggers,
configureStdlibLog, loadOrCreateConfig, buildRuntimeDeps,
makeHTTPLogSubscriber, shutdownManager. Signal-loop and fsnotify
watcher exit cleanly on ctx.Done() (previously chan-based with
unconditional os.Exit).

Behaviour preserved by smoke checks: -version, -update, generate
without --context, generate with bogus context, -check on
missing/valid config, -headless start+SIGINT shutdown.

Coverage: cmd/kportal 17.4% -> 71.3%. New run_test.go exercises
run() and every run* mode. main() and runInteractive remain at 0%
(TTY-required); not feasible without a tea.Program factory
abstraction, which would add complexity for minimal coverage gain.
2026-05-06 15:03:16 +01:00
lukaszraczylo b7b297c576 test: make MockStatusUpdater thread-safe for concurrent callbacks
The mock recorded calls into unprotected slices while being invoked
concurrently from the test goroutine and from the health-checker
callback registered by Manager.startWorker (and the watchdog hung
callback). go test -race -count=20 reliably tripped the race detector
on TestStartWorker_HealthCallback_StatusChange.

Wrap the slice writes in a sync.Mutex. Read-side code in tests reads
only after manager.Stop() drains the background goroutines (Stop's
wg.Wait establishes a happens-before edge), so direct reads remain
race-free.
2026-05-06 15:02:59 +01:00
lukaszraczylo 90ddca6709 test: cover ui handlers/views/commands/table
internal/ui: 27.9% -> 79.8%. Adds three test files (~3300 lines):
  - wizard_handlers_extended_test.go: keyboard branches not previously
    covered (ctrl+c, pgup/pgdn, search filter typing, port-checked
    failure path, alias text edit, focus toggling, error states),
    plus removeForwardsCmd / removeForwardByIDCmd against real Mutator
    + tempdir config (dedup + at-least-one-namespace validation).
  - wizard_views_test.go: every renderXxx path with a populated
    AddWizardState — context/namespace selectors, resource selection,
    port entry, http log list/detail, success, scroll indicators.
  - table_test.go: AddForward / UpdateStatus / SetError / Clear /
    FilterStrings flows.

Test-only fixups noted by agent:
  - getFilteredEntries silently skips StatusCode==0 entries (only
    completed responses are visible). Tests now seed StatusCode=200.
  - handleForwardSaved leaves step=StepConfirmation on save error
    rather than advancing to StepSuccess; assertion corrected.
  - removeForwardsCmd needs >=2 forwards in a context for dedup tests
    so removing one leaves the context non-empty (validator rejects
    empty contexts).

go test -race -count=1 ./... clean across all 14 packages.
2026-05-06 14:08:58 +01:00
lukaszraczylo ed80015e23 test: cover forward manager/worker/watchdog/portchecker
internal/forward: 45.9% -> 70.8%. Adds 14 critical-gap tests:
  - Manager.startWorker registration + duplicate error + healthcheck
    callback paths (status changes via MarkStarting/MarkReconnecting)
    + watchdog hung-callback (backdated heartbeat + checkWorkers).
  - stopWorker delegate + stopWorkerInternal removeFromUI=false.
  - DisableForward / EnableForward all error paths.
  - Reload diff logic: remove-stale, keep-unchanged, port conflict,
    empty new-config, currentConfig update.
  - SetMDNSPublisher trivial setter.
  - Watchdog.RegisterWorkerWithResponder alive/dead/transition cycle
    + pollHeartbeats direct + monitorLoop heartbeat ticker branch.
  - ForwardWorker.sleepWithBackoff (normal/cancelled/verbose) +
    IsAlive doneChan branch + Start terminates on cancel.
  - Manager.Start port-conflict path.
  - getProcessUsingPortUnix empty-bound and active-bound paths.

Remaining gaps (untestable without refactoring):
  - Windows-only branches (build tag prevents execution on macOS/Linux)
  - worker.run / establishForward — need a fake k8s.PortForwarder, but
    the Manager field is *k8s.PortForwarder (concrete), so a mock
    cannot be injected without source-level refactor.
2026-05-06 14:08:56 +01:00
lukaszraczylo fbb13aa32f test: cover converter I/O + httplog round-trip
internal/converter: 57.1% -> 98.4%. Added 18 cases covering
ConvertKFTrayToKPortal (happy path, missing input, malformed JSON,
unwritable output, multi-entry, file mode 0600), GetConversionSummary
(happy path, missing/malformed input, empty array, dedup counters),
and convertToKPortal edge cases (empty input, zero ports, empty
WorkloadType, sort order, alias preservation, tcp/udp/empty protocol
variants).

internal/httplog: 55.7% -> 95.7%. Added 17 tests using httptest for
loggingTransport.RoundTrip (GET/POST, filter-path bypass, header
redaction at the integration layer, backend-down, nil bodies, request
counter monotonicity) and direct unit tests for readBodyLimited
(empty, small, exact-at-limit, truncated, large pool-branch, zero
maxSize).
2026-05-06 14:08:54 +01:00
lukaszraczylo 1b2516ce82 test: cover cmd/kportal helpers + version checker HTTP paths
cmd/kportal: 0% -> 17.4% (testable surface only — main() is a
274-statement monolith with OS signals, bubbletea TUI, kubeconfig
loading, signal-loop goroutines, and config watcher all in one
function. Hitting 70% requires extracting it into run(args,w) int,
which is a non-trivial refactor — out of scope for a coverage pass.)
Tests cover: promptCreateConfig (yes/no/EOF/empty inputs via os.Pipe
stdin redirection), contains, resolveGenerateConfigPath (all 4 system
dirs + abs/rel branches), runGenerate (missing flag, -h, unknown
flag, invalid context, malformed YAML, no-TTY error path).

internal/version: 45.7% -> 97.8%. Added httptest.NewServer + custom
rewriteTransport to redirect GitHub API calls. Covered NewChecker,
fetchLatestRelease (200/403/404/429/500, malformed JSON, empty
tag_name), CheckForUpdate (newer/same/current-newer/error/cancelled),
parseVersion edge cases (empty, single digit, alpha).
2026-05-06 14:08:51 +01:00
lukaszraczylo f4adeedb8f feat: 'kportal generate' subcommand to bulk-add forwards from a cluster
New subcommand that connects to a chosen kube context and walks the
user through three picker steps before writing forwards to the config:

  1. Namespace multi-select (no system-namespace exclusion)
  2. Service multi-select grouped by namespace, with already-configured
     rows greyed out and locked off
  3. Starting-port input with a live preview of consecutive local-port
     assignments, skipping any port already taken by the existing config
     or another row in the batch

Multi-port services emit one forward per port. Non-TCP ports are
skipped with a one-line warning at the end (kportal forward layer is
TCP-only). --dry-run prints the planned forwards without writing.

Subcommand dispatch lives in cmd/kportal/main.go: when os.Args[1] ==
'generate', runGenerate(os.Args[2:]) is invoked before the main
flag.Parse() so the flag.NewFlagSet 'generate' parses its own
'--context', '--config', '--dry-run' flags. Invalid contexts list
the available ones for quick correction.

Tests in internal/ui/generate_test.go cover:
  - namespace toggle / toggle-all / filter
  - service multi-select with locked already-configured rows and
    non-TCP filtering
  - port-collision-aware consecutive assignment using a real Mutator
    against a tempdir config
  - reject + recover for starting-port < 1024
  - dry-run does not invoke the mutator
  - end-to-end Update() walk through the three steps
  - parse-starting-port boundary table
  - port-step view rendering
  - ServiceCandidate.Key() determinism

README updated with a 'Generate Forwards from a Cluster' section
describing the flow and the three flags.
2026-05-06 13:09:12 +01:00
lukaszraczylo e02edb68ef update dependencies 2026-05-06 12:49:28 +01:00
lukaszraczylo dbc7830546 fix(ui): edit-mode wizard allows keeping the same local port
Previously, editing a forward and keeping its local port unchanged
failed the wizard's port-availability check: the in-config scan
found the forward's own entry and reported '✗ Port N already
assigned to <self.ID>'. Users had to pick a different port,
edit, then change back.

checkPortCmd now accepts an excludeID. The wizard passes
wizard.originalID when isEditing so the forward being edited is
ignored during the in-config conflict scan. The OS-level port
check is unchanged (still catches actual port collisions).

New regression test: TestCheckPortCmd_ExcludeID_AllowsKeepingOwnPort.
2026-05-06 12:45:35 +01:00
lukaszraczylo bfe541565b feat(ui): toggle httpLog per-forward in add/edit wizard
Adds an HTTP-log enable toggle to the wizard's confirmation step so
users can flip httpLog on a forward without editing YAML by hand.

Behaviour:
- 'h' on the confirmation step toggles HTTPLog when not focused on
  the alias text input. When focus is on alias, 'h' is treated as
  text so users can still type aliases like 'host' or 'http-proxy'.
- The confirmation summary shows '[x] enabled' or '[ ] disabled'.
- New forwards: toggle on -> &HTTPLogSpec{Enabled: true}; off -> nil.
- Edit mode: pre-populates the toggle from the existing forward and
  preserves any advanced HTTPLog fields the user had configured in
  YAML (logFile, includeHeaders, maxBodySize, filterPath) by copying
  the original spec on save. Toggling off discards the advanced
  fields (consistent with 'absent in YAML = disabled').

State changes:
- ForwardStatus gains *config.HTTPLogSpec so the wizard can see the
  full original spec on edit.
- AddWizardState gains httpLog bool + httpLogOriginal *HTTPLogSpec.

Three new tests:
- TestHandleAddWizardKeys_HToggleHTTPLog
- TestHandleAddWizardKeys_HOnAliasFocusIsTextInput
- TestEditPrefill_PreservesHTTPLog
2026-05-06 12:41:36 +01:00
lukaszraczylo c413b808f1 fix(config): allow @ . : / in context names
Real kubeconfig context names commonly contain characters the
validator rejected:
  - 'admin@home', '[email protected]' (kubectl rename, EKS
    aws-iam-authenticator)
  - 'cluster.example.com', 'gke_proj_zone_cluster.prod' (FQDN, GKE)
  - 'arn:aws:eks:us-east-1:123:cluster/foo' (EKS ARN)

kubeconfig itself imposes no character restrictions, so requiring
[a-zA-Z0-9_-] only was kportal-specific over-validation that blocked
legitimate users. Widen the allowed set to add '@', '.', ':', '/'.
Names must still start and end with a letter or digit so YAML
specials and leading whitespace remain rejected.

Tests cover the new positive cases and tighten negative coverage
(starts-with-@, ends-with-/, ends-with-dot).
2026-05-06 12:11:37 +01:00
lukaszraczylo 0ccc855123 fix: Manager.Stop() is now idempotent
Previously a second Stop() call would panic from a double-close on
eventBus and re-stop the healthChecker/watchdog whose contexts had
already been cancelled. Wrapping the body in sync.Once makes
sequential and concurrent double-Stop safe.

TestManager_Stop_Idempotent covers both paths.
2026-05-06 11:02:41 +01:00
lukaszraczylo 0a8c872b01 fix(install): pin cosign cert-identity to shared-actions workflow
Releases are signed by the lukaszraczylo/shared-actions reusable
workflow, so the Sigstore certificate subject is the workflow URL
rather than this repo. The previous regex
'https://github.com/lukaszraczylo/kportal/.*' never matched, so any
user with cosign installed would see verification fail and abort
the install.

Pin cert-identity to the exact workflow URL:
  ^https://github\.com/lukaszraczylo/shared-actions/\.github/workflows/go-release\.yaml@refs/heads/main$

Override via COSIGN_CERT_IDENTITY_REGEXP for forks of the release
pipeline. Same fix applied to README's manual verification example.

Verified end-to-end against release v0.2.90:
  cosign verify-blob ... -> Verified OK
2026-05-06 11:02:40 +01:00
lukaszraczylo b4256dbbce fix(install): verify SHA-256 checksums + portable version parsing
P0 #8 — install.sh fetched and installed the binary with no integrity
check whatsoever, despite README claiming cosign verification. A
compromised release or registry MITM resulted in RCE on every
installer.

Now:
  - downloads checksums.txt alongside the archive (required; abort on
    missing)
  - computes local SHA-256 with shasum -a 256 (works on macOS+Linux,
    not GNU-only sha256sum)
  - aborts on mismatch with a clear error
  - if cosign is in PATH AND the sigstore bundle is present (the latter
    already published by goreleaser), verifies cert-identity. Skipped
    silently when cosign is absent so the install path still works for
    users without cosign installed.
  - SKIP_COSIGN=1 lets users opt out of cosign verification only
    (checksum verification is always enforced).
  - DRY_RUN=1 verifies + downloads but does not install, for testing.

Also replaced GNU-only `grep -oP` (silently fails on macOS BSD grep)
with portable awk for parsing kportal --version.

NOTE: the cosign cert-identity regex matches lukaszraczylo/kportal/.*
but actual releases are signed from the shared-actions reusable
workflow. Users with cosign installed will currently see a verification
failure on real releases. Either widen the regex to lukaszraczylo/.*
or change the signing identity scheme — flagging for follow-up.

README install section updated to mention the new verification.
2026-05-06 10:45:45 +01:00
lukaszraczylo 95bda3ee3b fix: redact sensitive headers in httplog + restore headless logging
P0 #1 — HTTP traffic logger captured Authorization, Cookie, Set-Cookie,
X-Api-Key, X-Auth-Token, X-Csrf-Token, Proxy-Authorization, X-Access-Token
verbatim into log entries (file 0600 + UI subscribers). Bearer tokens
and session cookies were ending up on disk whenever httpLog.includeHeaders
was enabled.

flattenHeaders now redacts:
  - the explicit list above (case-insensitive via http.CanonicalHeaderKey)
  - any header name containing 'token', 'secret', 'password', 'apikey'
Header names remain visible; values become [REDACTED].
Redaction is unconditional and on-by-default — no opt-out flag. Users
who want raw headers can use tcpdump.

P0 #6 — Headless mode without -v silently routed both structured and
stdlib logs to io.Discard. A daemon under launchd/systemd had no way to
report errors. Headless now defaults log destination to os.Stderr; -v
controls only the level (debug vs info). TUI-quiet path is preserved.

Tests in internal/httplog/redact_test.go cover all explicit names,
substring patterns, and case variants.
2026-05-06 10:45:29 +01:00
lukaszraczylo 4fe3f6b21f fix(ui): Esc cancels delete confirmation instead of confirming it
In the remove-wizard's confirming state, pressing Esc was reflexively
calling removeForwardsCmd — i.e. confirming deletion. The on-screen
help text said 'Esc: Cancel'. Reflexive Esc-to-cancel destroyed data.

Esc now sets confirming=false and resets the cursor; deletion
requires Enter on Yes. Non-confirming Esc behavior (exit wizard with
ClearScreen) is unchanged.

Three regression tests added in handlers_test.go.
2026-05-06 10:45:27 +01:00
lukaszraczylo 7a33e01863 fix: 4 P0 concurrency races in forward + k8s
P0 #2 — currentConfig data race
  Manager.currentConfig was written without locking in Start/Reload but
  read from the health-checker callback goroutine. All accesses now go
  through workersMu (read or write as appropriate).

P0 #3 — Reload kills health checker permanently
  Reload's zero-forward branch called m.Stop() which tore down the
  health checker, watchdog, and event bus. After that, EnableForward
  silently registered callbacks against dead components. Now the branch
  stops only the running workers; the supervisory infrastructure stays
  alive across config changes.

P0 #4 — rest.Config write-write race
  executePortForward was mutating .Dial on the cached *rest.Config
  shared by all forwards in the same kube context. Cloning the config
  with rest.CopyConfig before mutation isolates per-forward dialers.

P0 #5 — ForwardWorker.Stop() double-close panic
  close(w.stopChan) is now wrapped in sync.Once, so concurrent Stop
  calls (Manager.Stop racing stopWorkerInternal) are safe.

New tests in internal/forward/concurrency_test.go exercise each fix
under -race: 16 concurrent worker Stops, repeated sequential Stops,
empty-Reload preserves infra pointers, and concurrent currentConfig
read/write.
2026-05-06 10:45:10 +01:00
lukaszraczylo 614b6e6396 test: relax TestDiscovery_GetCurrentContext for empty kubeconfig
CI runners have no kubeconfig, so clientcmd's loader returns an empty
config (no error) and CurrentContext == "". The previous assertion
'NotEmpty(context)' on the success branch was incorrect — an empty
current-context is valid for an empty kubeconfig.

Mirrors the looser pattern in TestDiscovery_ListContexts.
2026-05-06 10:34:46 +01:00
lukaszraczylo 8e5eaab0af fixup! Update go.mod and go.sum (#48) 2026-02-20 15:39:27 +00:00
lukaszraczyloandGitHub 0aaf2dc78c Update go.mod and go.sum (#48) 2026-02-18 03:55:50 +00:00
lukaszraczyloandGitHub d945e4915d Update go.mod and go.sum (#47) 2026-02-17 03:54:37 +00:00
lukaszraczyloandGitHub e50f73ec92 chore: add golangci-lint v2 config and fix linter warnings (#46)
- [x] Add golangci-lint v2 configuration with formatters section
- [x] Reorganize linters-settings under linters section
- [x] Replace if-else chains with switch statements for clarity
- [x] Wrap all ignored error returns with `_ = ` pattern
- [x] Add OSC 8 hyperlink helper function for clickable ports
- [x] Add blank line in table styling function
- [x] Remove unnecessary type assertion in test
2026-02-13 18:46:27 +00:00
lukaszraczyloandGitHub d3c5e5eb36 Update go.mod and go.sum (#45) 2026-02-13 03:57:21 +00:00
lukaszraczyloandGitHub 34e6fc60da Update go.mod and go.sum (#44) 2026-02-11 04:03:09 +00:00
lukaszraczyloandGitHub fde40f253c Update go.mod and go.sum (#42) 2026-02-10 04:04:32 +00:00
lukaszraczyloandGitHub 9497b6d705 Update go.mod and go.sum (#41) 2026-02-09 04:00:55 +00:00
lukaszraczyloandGitHub e6bd540306 Update go.mod and go.sum (#40) 2026-02-07 03:52:04 +00:00
lukaszraczyloandGitHub 86d91e0071 Update go.mod and go.sum (#39) 2026-02-05 03:53:12 +00:00
lukaszraczyloandGitHub 4eff5ff5eb Update go.mod and go.sum (#38) 2026-02-04 03:53:00 +00:00
lukaszraczyloandGitHub b9b7d5ec87 Update go.mod and go.sum (#37) 2026-02-02 03:57:42 +00:00
lukaszraczyloandGitHub bc3b61e778 Update go.mod and go.sum (#36) 2026-01-28 03:40:33 +00:00
lukaszraczyloandGitHub 676fd3df39 Update go.mod and go.sum (#35) 2026-01-26 03:45:09 +00:00
lukaszraczyloandGitHub 00380ca307 Update go.mod and go.sum (#34) 2026-01-25 03:43:03 +00:00
lukaszraczyloandGitHub e4930071fc Update go.mod and go.sum (#33) 2026-01-23 03:40:40 +00:00
lukaszraczyloandGitHub c43aca3805 Update go.mod and go.sum (#32) 2026-01-19 03:42:14 +00:00
lukaszraczyloandGitHub 4add04e3be Update go.mod and go.sum (#31) 2026-01-16 03:39:04 +00:00
lukaszraczyloandGitHub 96ae1d45e0 style: Extract UI constants and refactor main view rendering (#30)
- [x] Add golangci-lint configuration with gocritic ifElseChain disabled
- [x] Rename error variables to avoid shadowing (createErr, watcherErr, watchErr, etc.)
- [x] Replace `interface{}` with `any` type alias throughout codebase
- [x] Add package-level documentation comments to all internal packages
- [x] Reorder struct fields alphabetically for consistency
- [x] Extract UI constants (terminal dimensions, column widths, colors) to constants.go
- [x] Refactor BubbleTeaUI main view rendering into smaller helper functions
- [x] Simplify nested conditionals and improve code clarity
- [x] Add `isForwardDisabled()` helper method to BubbleTeaUI
- [x] Update file permissions from 0644 to 0600 in config tests
- [x] Add `#nosec` comments and error suppression where appropriate
- [x] Improve test table struct field ordering for readability
- [x] Fix resource parsing in AddForward using strings.SplitN
- [x] Add comprehensive tests for new UI helper functions and constants
2026-01-13 09:37:45 +00:00
lukaszraczyloandGitHub 3d71f64901 Update go.mod and go.sum (#29) 2026-01-13 03:39:00 +00:00
lukaszraczyloandGitHub 38b7a06c53 Update go.mod and go.sum (#28) 2026-01-12 03:41:55 +00:00
lukaszraczyloandGitHub 7ad96e3f72 Update go.mod and go.sum (#27) 2026-01-10 03:37:23 +00:00
lukaszraczyloandGitHub ac7c855de5 Update go.mod and go.sum (#26) 2026-01-09 03:39:39 +00:00
lukaszraczyloandGitHub 4074a7186c Update go.mod and go.sum (#25) 2026-01-07 03:39:19 +00:00
lukaszraczyloandGitHub a5cc95a26e Update go.mod and go.sum (#24) 2025-12-23 03:39:14 +00:00
lukaszraczyloandGitHub 0f977683cd Update go.mod and go.sum (#23) 2025-12-21 03:39:29 +00:00
lukaszraczyloandGitHub dcebdf718a Update go.mod and go.sum (#22) 2025-12-20 03:32:25 +00:00
lukaszraczyloandGitHub 5967f26c21 Update go.mod and go.sum (#21) 2025-12-19 03:37:51 +00:00
lukaszraczylo 285ced6755 fixup! Update go.mod and go.sum (#20) 2025-12-18 09:38:02 +00:00
lukaszraczyloandGitHub 9fe076acb2 Update go.mod and go.sum (#20) 2025-12-18 03:37:26 +00:00
lukaszraczyloandGitHub 92746efcf5 Update go.mod and go.sum (#19) 2025-12-15 03:40:40 +00:00
lukaszraczylo 391bce366d fixup! fixup! Add artifacts signing. 2025-12-15 00:16:16 +00:00
lukaszraczylo 9fd8f9b03b fixup! Add artifacts signing. 2025-12-14 23:56:42 +00:00
lukaszraczylo 7032bb5bee Add artifacts signing. 2025-12-14 23:29:27 +00:00
lukaszraczylo 6cb4f91ece Cleanup and refactor. 2025-12-14 18:17:20 +00:00
lukaszraczyloandGitHub 5d600043f0 Update go.mod and go.sum (#18) 2025-12-13 03:32:36 +00:00
lukaszraczyloandGitHub 9bb6fbc48d Update go.mod and go.sum (#17) 2025-12-12 03:38:34 +00:00
lukaszraczyloandGitHub f4334ebdc9 Update go.mod and go.sum (#16) 2025-12-11 03:38:45 +00:00
lukaszraczyloandGitHub 50f94bda87 Update go.mod and go.sum (#15) 2025-12-09 01:13:24 +00:00
lukaszraczyloandGitHub d9888f1a56 Cleanup (#14)
* Codebase cleanup
2025-12-09 01:06:38 +00:00
lukaszraczylo 7dec532e18 Use shared PR workflow 2025-12-08 01:32:30 +00:00
lukaszraczylo aa7695b3be Trigger autoupdate. 2025-12-08 01:10:11 +00:00
lukaszraczylo 1bacd31f27 fixup! Add verified param to the releaser. 2025-12-07 16:40:37 +00:00
lukaszraczylo bfecbdf056 Add verified param to the releaser. 2025-12-07 14:40:12 +00:00
lukaszraczylo 754108474c fixup! fixup! fixup! Update gorelease config and docs - moving to cask due to depreciation 2025-12-07 14:36:45 +00:00
lukaszraczylo 690c587c0a fixup! fixup! Update gorelease config and docs - moving to cask due to depreciation 2025-12-07 14:16:43 +00:00
lukaszraczylo 0d03f228f9 fixup! Update gorelease config and docs - moving to cask due to depreciation 2025-12-07 14:04:38 +00:00
lukaszraczylo 2a44c6ff9c Update gorelease config and docs - moving to cask due to depreciation 2025-12-07 13:59:51 +00:00
lukaszraczylo 8672d932bb Move build and release to shared workflow 2025-12-07 13:34:14 +00:00
lukaszraczylo 87317adb91 Move to shared workflow. 2025-12-07 13:16:41 +00:00
lukaszraczylo ced7e80a06 Update the autoupdate workflow 2025-12-07 12:35:56 +00:00
lukaszraczylo 13723733df Update autoupdate workflow. LOL. 2025-12-03 00:47:06 +00:00
lukaszraczylo 9538623bcb Remove unused struct 2025-12-02 18:13:05 +00:00
lukaszraczylo 8bb377909c Add startupSettleTime to zeroconf to avoid race conditions. 2025-12-02 18:06:11 +00:00
lukaszraczylo 263a0370d3 fixup! fixup! Fix autoupdate workflow. 2025-12-01 14:39:54 +00:00
lukaszraczylo ea20a037b9 fixup! Fix autoupdate workflow. 2025-12-01 14:31:06 +00:00
lukaszraczylo 46db732f87 Fix autoupdate workflow. 2025-12-01 14:24:34 +00:00
lukaszraczylo a297ba7073 Enhancement: Empty config
When user starts kportal for the first time, and there is no config file,
kportal should create an empty config file with default values and empty
forwarding rules, so that user can easily edit the config file and add their
own rules.
2025-11-29 12:44:33 +00:00
lukaszraczylo 518879dc56 Update menus to wrap for smaller screens. 2025-11-29 02:09:54 +00:00
lukaszraczylo 649227b201 Update taps confusion. 2025-11-29 01:39:21 +00:00
lukaszraczyloandGitHub 28e2fc315a Create CNAME 2025-11-28 00:29:37 +00:00
lukaszraczylo ba77cb6aa9 Use OS native copy. 2025-11-26 13:28:20 +00:00
lukaszraczyloandGitHub 23cd45a3d7 improvements nov2025 pt2 (#13)
* Further improvements

| Fix                                | Impact                                 | Files Modified                       |
|------------------------------------|----------------------------------------|--------------------------------------|
| sync.Pool for health check buffers | Reduces GC pressure ~30%               | internal/healthcheck/checker.go      |
| Goroutine leak fix + sync.Once     | Prevents memory leaks                  | internal/forward/worker.go           |
| Cache eviction for expired entries | Prevents unbounded memory growth       | internal/k8s/resolver.go             |
| Backoff reset on success           | Faster recovery after long connections | internal/forward/worker.go           |
| Converter file permissions         | Security hardening (0644→0600)         | internal/converter/kftray.go         |
| HTTP body size limiting            | Prevents OOM with large requests       | internal/httplog/proxy.go, logger.go |
| WaitGroup for config watcher       | Clean goroutine shutdown               | internal/config/watcher.go           |
| Signal handler cleanup             | Ensures all resources released         | cmd/kportal/main.go                  |

* Additional event bus for internal event handling

| Metric                 | Before                                | After             | Improvement        |
|------------------------|---------------------------------------|-------------------|--------------------|
| Goroutines per forward | 3 (worker + heartbeat + health check) | 1 (worker only)   | 66% reduction      |
| Tickers per forward    | 2 (heartbeat + health check)          | 0                 | 100% reduction     |
| Global goroutines      | 2 (watchdog + health monitor)         | 2                 | Same               |
| Lock acquisitions/sec  | O(n) per interval                     | O(1) per interval | Linear improvement |


* Add UI testing
* Add mocks
* Add more logs and details to be displayed
2025-11-26 13:18:50 +00:00
lukaszraczyloandGitHub dbbc96a200 Improve mobile responsiveness for documentation website (#12) 2025-11-25 21:42:15 +00:00
lukaszraczyloandGitHub 2498a3aa98 improvements nov2025 (#11)
* Add benchmark and httplog modules, update UI for modals artefacts
2025-11-25 19:06:17 +00:00