Documentation
¶
Index ¶
Constants ¶
View Source
const ( WarningCodeAccessLogDrops = "access_log_drops" )
View Source
const ( WarningCodeTCPHTTPACLNotApplicable = "tcp_http_acl_not_applicable" WarningCodeTCPAllowedUsersInvalid = "tcp_allowed_users_invalid" WarningCodeServiceTypeUnknown = "service_type_unknown" WarningCodeRuntimeSnapshotMissing = "runtime_snapshot_missing" WarningCodeRuntimeSnapshotStale = "runtime_snapshot_stale" WarningCodeRuntimeSnapshotUnreadable = "runtime_snapshot_unreadable" WarningCodeFunnelAllowConflict = registry.CodeFunnelAllowConflict WarningCodeFunnelPublicAckRequired = registry.CodeFunnelPublicAckRequired WarningCodeFunnelExpiryRequired = registry.CodeFunnelExpiryRequired WarningCodeFunnelControlURLConflict = registry.CodeFunnelControlURLConflict WarningCodeFunnelTypeConflict = registry.CodeFunnelTypeConflict WarningCodePathNotFound = registry.CodePathNotFound WarningCodePathNotDirectory = registry.CodePathNotDirectory WarningCodePathNotAccessible = registry.CodePathNotAccessible WarningCodePathExposesConfigDir = registry.CodePathExposesConfigDir WarningCodeFileRootHomeDirectory = "file_root_home_directory" WarningCodeAccessChangedOnReplace = "access_changed_on_replace" WarningCodeIdentityResetOnReplace = "identity_reset_on_replace" WarningCodeRegistryRecreated = "registry_recreated_with_node_state" WarningCodeConfigLoadFailed = registry.CodeConfigLoadFailed WarningCodeRegistryLoadFailed = "registry_load_failed" WarningCodeRegistryServiceInvalid = "registry_service_invalid" WarningCodeControlURLInvalid = "control_url_invalid" WarningCodeCredentialNone = "credential_none" WarningCodeCredentialTier1 = "credential_tier1" WarningCodeCredentialLegacyAuthKey = "credential_legacy_authkey" WarningCodeCredentialNoAPIClient = "credential_no_api_client" WarningCodeCredentialReadFailed = "credential_read_failed" WarningCodeDaemonIdentityUnverified = "daemon_identity_unverified" WarningCodeDaemonBuildSkew = "daemon_build_skew" WarningCodeDaemonNotRunning = "daemon_not_running" WarningCodeDaemonUnsupervised = "daemon_unsupervised" WarningCodeTargetProbeSkippedDaemon = "target_probe_skipped_daemon_not_running" WarningCodeDaemonPIDUnreadable = "daemon_pid_unreadable" WarningCodeTargetProbeSkippedExternal = "target_probe_skipped_external" WarningCodeTargetProbeFailed = "target_probe_failed" WarningCodeTargetProbeRefused = "target_probe_refused" WarningCodeTargetProbeTimeout = "target_probe_timeout" WarningCodeTargetInvalid = "target_invalid" WarningCodeProxyNonLoopbackTarget = "proxy_non_loopback_target" WarningCodeTCPNonLoopbackTarget = "tcp_non_loopback_target" WarningCodeFilePathMissing = "file_path_missing" WarningCodeFilePathUnreadable = "file_path_unreadable" WarningCodeFunnelGlobalControlURLUnknownCompat = "funnel_global_control_url_unknown_compat" WarningCodeIdentityResolutionUnknown = "identity_resolution_unknown" WarningCodeDeviceCleanupBlocked = "device_cleanup_blocked" WarningCodeCredentialMixedRecommended = "credential_mixed_recommended" WarningCodeCredentialAPITokenOnly = "credential_api_token_only" WarningCodeCredentialOAuthClientOnly = "credential_oauth_client_only" WarningCodeCredentialAPITokenExpiring = "credential_api_token_expiring" WarningCodeCredentialAPITokenExpired = "credential_api_token_expired" WarningCodeCredentialExpiryUnknown = "credential_expiry_unknown" WarningCodeCredentialRemoteUnverified = "credential_remote_unverified" WarningCodeCredentialMetaBackfilled = "credential_meta_backfilled" WarningCodeCredentialAPITokenRejected = "credential_api_token_rejected" WarningCodeCredentialRemoteForbidden = "credential_remote_forbidden" WarningCodeCredentialRemoteUnreachable = "credential_remote_unreachable" // Tailscale SSH is a tailscaled feature, not a TSLink feature. These three // codes are always informational: they report what the local Tailscale // client says about this node so an operator discovers the zero-code remote // path, and they never change doctor's health status or exit code. WarningCodeTailscaleSSHEnabled = "tailscale_ssh_enabled" WarningCodeTailscaleSSHDisabled = "tailscale_ssh_disabled" WarningCodeTailscaleSSHUnknown = "tailscale_ssh_unknown" )
View Source
const ( WarningCodeHealthMonitorSaturated = "health_monitor_saturated" WarningCodeAppProbeFailed = "app_probe_failed" WarningCodeAppProbeUnexpected = "app_probe_unexpected_response" WarningCodeNodeKeyExpiring = "node_key_expiring" WarningCodeNodeKeyCritical = "node_key_expiry_critical" WarningCodeNodeKeyExpired = "node_key_expired" WarningCodeNodeKeyUnknown = "node_key_expiry_unknown" WarningCodeCredentialCritical = "credential_expiry_critical" )
View Source
const ( // SchemaVersion is the version of the public data views (list, status // --urls, doctor, access explain, templates, the service view). It is an // integer like the envelope's, registry.json's and runtime.json's own // schema_version; runtime.json keeps its own number. SchemaVersion = 1 EndpointKindHTTPS = "https" EndpointKindPublicHTTPS = "public_https" EndpointKindTCP = "tcp" EndpointKindUnknown = "unknown" EndpointStateExact = "exact" EndpointStateExpected = "expected" ExposureTailnet = "tailnet" ExposureTailnetAllow = "tailnet_allow" ExposurePublicFunnel = "public_funnel" ExposureGuestFunnel = "guest_funnel" ExposureUnknown = "unknown" )
View Source
const WarningCodeGuestCounters = "guest_counters_persistence_failed"
View Source
const WarningCodeGuestExpiry = "guest_link_expiring"
View Source
const WarningCodeGuestFunnel = "guest_funnel_unavailable"
Variables ¶
View Source
var WarningCodeRegistry = map[string]WarningCodeMeta{ registry.CodeRequestBodyLimit: {Severity: "warning", Source: "http.request_limits", Description: "An HTTP upload exceeded this service's body size limit; adjust --max-request-body."}, registry.CodeRequestReadTimeout: {Severity: "warning", Source: "http.request_limits", Description: "An HTTP upload stopped making progress; adjust --request-read-timeout."}, registry.CodeRequestHeaderTimeout: {Severity: "warning", Source: "http.request_limits", Description: "An HTTP request exceeded the header timeout; adjust --request-header-timeout."}, registry.CodeInvalidRequestLimits: {Severity: "error", Source: "service.request_limits", Description: "HTTP request limits are invalid."}, WarningCodeTCPHTTPACLNotApplicable: { Severity: "warning", Source: "service.type", Description: "Raw TCP services are private tsnet routes; TSLink HTTP identity and allow filtering do not apply.", }, WarningCodeTCPAllowedUsersInvalid: { Severity: "error", Source: "service.allowed_users", Description: "Raw TCP services cannot enforce allowed_users; remove the allow list or convert the service to HTTP.", }, WarningCodeServiceTypeUnknown: { Severity: "warning", Source: "service.type", Description: "The registry contains a service type unknown to this TSLink version.", }, WarningCodeRuntimeSnapshotMissing: { Severity: "warning", Source: "runtime.snapshot", Description: "No runtime snapshot is available, so exact runtime endpoints cannot be proven.", }, WarningCodeRuntimeSnapshotStale: { Severity: "warning", Source: "runtime.snapshot", Description: "The runtime snapshot is readable but does not match the current daemon or registry, or is partial while the registry is being synchronized.", }, WarningCodeRuntimeSnapshotUnreadable: { Severity: "warning", Source: "runtime.snapshot", Description: "The runtime snapshot could not be read: a filesystem or permission error, malformed JSON, or a schema_version this build does not understand.", }, WarningCodeFunnelAllowConflict: { Severity: "error", Source: "service.allowed_users", Description: "Public Funnel services cannot be combined with TSLink allow lists.", }, WarningCodeFunnelPublicAckRequired: { Severity: "error", Source: "service.public_ack", Description: "Public Funnel services require recorded public acknowledgement.", }, WarningCodeFunnelExpiryRequired: { Severity: "error", Source: "service.funnel_expires_at", Description: "A Funnel entry records neither a deadline nor \"never\"; the daemon does not start it until one is set.", }, WarningCodeFunnelControlURLConflict: { Severity: "error", Source: "service.control_url", Description: "Public Funnel services cannot use per-service control_url.", }, WarningCodeFunnelTypeConflict: { Severity: "error", Source: "service.type", Description: "Public Funnel services can only be proxy services.", }, WarningCodePathNotFound: { Severity: "error", Source: "service.path", Description: "A configured file service directory does not exist.", }, WarningCodePathNotDirectory: { Severity: "error", Source: "service.path", Description: "A configured file service path is not a directory.", }, WarningCodePathNotAccessible: { Severity: "error", Source: "service.path", Description: "A configured file service path is not accessible to the current user.", }, WarningCodePathExposesConfigDir: { Severity: "error", Source: "service.path", Description: "A file service path is, contains, or lies inside TSLink's config directory; it is refused so node keys and credentials are never served.", }, WarningCodeFileRootHomeDirectory: { Severity: "warning", Source: "service.path", Description: "A directory share serves the user's whole home directory, dotfiles included; it is accepted only because TSLink's config directory lives elsewhere.", }, WarningCodeAccessChangedOnReplace: { Severity: "warning", Source: "cmd.add", Description: "add replaced an existing service and changed its allow list, tags or Funnel; settings not given again were dropped.", }, WarningCodeIdentityResetOnReplace: { Severity: "warning", Source: "cmd.add", Description: "add replaced an existing service and changed its tags, ephemeral flag or control URL; the daemon re-enrolls it as a new tailnet node.", }, WarningCodeRegistryRecreated: { Severity: "warning", Source: "registry.create", Description: "add or share created registry.json while the config directory still held node state, identity records or ownership rows for services not in it; if registry.json was lost, restore it before adding services.", }, WarningCodeConfigPathUnavailable: { Severity: "error", Source: "config.path", Description: "TSLink config paths could not be discovered locally.", }, WarningCodeConfigLoadFailed: { Severity: "error", Source: "config.global", Description: "TSLink global config could not be loaded.", }, WarningCodeRegistryLoadFailed: { Severity: "critical", Source: "registry.load", Description: "TSLink registry could not be loaded.", }, WarningCodeRegistryServiceInvalid: { Severity: "error", Source: "registry.service", Description: "A registry service failed validation.", }, WarningCodeControlURLInvalid: { Severity: "error", Source: "control_url", Description: "A configured control_url is not a valid HTTP or HTTPS URL.", }, WarningCodeCredentialNone: { Severity: "info", Source: "credentials", Description: "Tier 1 interactive enrollment has not started; run tslink serve, or use tslink login only for optional Tier 2.", }, WarningCodeCredentialTier1: { Severity: "info", Source: "credentials", Description: "TSLink is using the default Tier 1 interactive-enrollment path without a stored administrative credential.", }, WarningCodeCredentialLegacyAuthKey: { Severity: "warning", Source: "credentials", Description: "A legacy reusable auth key is configured; API token or OAuth client secret is preferred.", }, WarningCodeCredentialNoAPIClient: { Severity: "info", Source: "credentials", Description: "Configured credentials can start services but do not provide a local Tailscale API client.", }, WarningCodeCredentialReadFailed: { Severity: "error", Source: "credentials", Description: "Stored credentials could not be inspected locally.", }, WarningCodeDaemonIdentityUnverified: {Severity: "warning", Source: "daemon", Description: "Daemon process identity is unverified; preserve probes and inspect before restarting."}, WarningCodeDaemonBuildSkew: { Severity: "warning", Source: "daemon", Description: "The running daemon's own reported build differs from this CLI invocation's build, so an upgraded binary is not yet the one actually serving; run 'tslink install' to restart the daemon with the current binary.", }, WarningCodeDaemonRestartUnavailable: {Severity: "warning", Source: "daemon", Description: "Sign-in startup is installed but crash restart is unavailable."}, WarningCodeDaemonNotRunning: { Severity: "error", Source: "daemon", Description: "The TSLink daemon is not currently running.", }, WarningCodeDaemonUnsupervised: { Severity: "error", Source: "daemon", Description: "Registered services have no verified supervisor/autostart.", }, WarningCodeTargetProbeSkippedDaemon: { Severity: "info", Source: "target_probe", Description: "Backend probe deferred until the TSLink daemon is running.", }, WarningCodeDaemonPIDUnreadable: { Severity: "warning", Source: "daemon.pid", Description: "The TSLink daemon appears to be running, but the PID file could not be read.", }, WarningCodeTargetProbeSkippedExternal: { Severity: "warning", Source: "target.probe", Description: "External target probing is skipped unless --probe-external is set.", }, WarningCodeTargetProbeFailed: { Severity: "error", Source: "target.probe", Description: "A target probe failed.", }, WarningCodeTargetProbeRefused: { Severity: "error", Source: "target.probe", Description: "A target probe was refused.", }, WarningCodeTargetProbeTimeout: { Severity: "error", Source: "target.probe", Description: "A target probe timed out.", }, WarningCodeTargetInvalid: { Severity: "error", Source: "target", Description: "A service target could not be parsed for local diagnostics.", }, WarningCodeProxyNonLoopbackTarget: { Severity: "warning", Source: "service.target", Description: "A proxy service points at a non-loopback target.", }, WarningCodeTCPNonLoopbackTarget: { Severity: "warning", Source: "service.target", Description: "A TCP service points at a non-loopback target.", }, WarningCodeFilePathMissing: { Severity: "error", Source: "service.path", Description: "A file service path does not exist.", }, WarningCodeFilePathUnreadable: { Severity: "error", Source: "service.path", Description: "A file service path is not readable as a directory.", }, WarningCodeFunnelGlobalControlURLUnknownCompat: { Severity: "warning", Source: "config.control_url", Description: "A global custom control_url is configured while Funnel services exist; compatibility cannot be proven locally.", }, WarningCodeIdentityResolutionUnknown: { Severity: "info", Source: "identity", Description: "Local diagnostics cannot prove real Tailscale identity resolution or remote ACL policy.", }, WarningCodeDeviceCleanupBlocked: { Severity: "warning", Source: "ownership", Description: "TSLink does not delete this service's tailnet device: an ownership record for it has no retired_at while the service is absent from registry.json, so nothing says it was removed. Restore the service in registry.json, or review the device and retire the record with tslink cleanup --adopt <hostname> --force --dry-run=false.", }, WarningCodeCredentialMixedRecommended: { Severity: "info", Source: "credentials", Description: "Both an OAuth client secret (durable daemon auth) and a user-owned API access token (invites) are stored; this is the recommended dual-slot configuration.", }, WarningCodeCredentialAPITokenOnly: { Severity: "warning", Source: "credentials", Description: "Only a user-owned API access token is stored: invites work, but daemon node authentication depends on a token that expires within 90 days; add an OAuth client secret for durable daemon auth.", }, WarningCodeCredentialOAuthClientOnly: { Severity: "info", Source: "credentials", Description: "Only an OAuth client secret is stored: daemon authentication is durable, but invite operations need a user-owned tskey-api- token.", }, WarningCodeCredentialAPITokenExpiring: { Severity: "warning", Source: "credentials", Description: "The stored API access token expires within 14 days; generate a new token and run tslink login --api-key-stdin before it lapses.", }, WarningCodeCredentialAPITokenExpired: { Severity: "error", Source: "credentials", Description: "The stored API access token has passed its recorded expiry; remote API calls that depend on it will fail with HTTP 401 until a new token is stored.", }, WarningCodeCredentialExpiryUnknown: { Severity: "warning", Source: "credentials", Description: "Credential metadata (credential-meta.json) is missing or unreadable, so token expiry cannot be evaluated locally.", }, WarningCodeCredentialRemoteUnverified: { Severity: "info", Source: "credentials", Description: "A stored credential has never been verified against the Tailscale API by this TSLink install; run tslink doctor --probe-remote to record a verification.", }, WarningCodeCredentialMetaBackfilled: { Severity: "info", Source: "credentials", Description: "Credential metadata was backfilled for a credential stored before expiry tracking existed; stored_at is the backfill time and expires_at is the assumed 90-day maximum.", }, WarningCodeCredentialAPITokenRejected: { Severity: "error", Source: "credentials", Description: "The remote probe was rejected with HTTP 401: the stored credential is expired, revoked, or invalid.", }, WarningCodeCredentialRemoteForbidden: { Severity: "warning", Source: "credentials", Description: "The remote probe was refused with HTTP 403: the credential is valid but its user role or OAuth scopes do not permit the probe operation.", }, WarningCodeCredentialRemoteUnreachable: { Severity: "warning", Source: "credentials", Description: "The remote probe could not reach the Tailscale API; the credential state remains unproven.", }, WarningCodeTailscaleSSHEnabled: { Severity: "info", Source: "tailscale_ssh", Description: "Tailscale SSH is enabled on this node, so `tailscale ssh <this-host> tslink <command>` can drive this install remotely once a tailnet ACL ssh rule permits the caller.", }, WarningCodeTailscaleSSHDisabled: { Severity: "info", Source: "tailscale_ssh", Description: "Tailscale SSH is disabled on this node. Run `tailscale set --ssh` here and add a tailnet ACL ssh rule to reach this install with `tailscale ssh <this-host> tslink <command>`; TSLink does not manage this tailscaled feature.", }, WarningCodeTailscaleSSHUnknown: { Severity: "info", Source: "tailscale_ssh", Description: "The local Tailscale client state could not be read, so Tailscale SSH enablement on this node is unknown. Check `tailscale status` on this machine.", }, }
Functions ¶
func SanitizeBackendDisplay ¶
SanitizeBackendDisplay preserves useful backend diagnostics while removing credential-bearing URL parts from public service views.
Types ¶
type BackendView ¶
type EndpointView ¶
type ExposureView ¶
type ServiceView ¶
type ServiceView struct {
RequestLimits *registry.EffectiveRequestLimits `json:"request_limits,omitempty"`
SchemaVersion int `json:"schema_version"`
Name string `json:"name"`
Type string `json:"type"`
Endpoint EndpointView `json:"endpoint"`
Exposure ExposureView `json:"exposure"`
Tags SummaryView `json:"tags"`
Allow SummaryView `json:"allow"`
Backend BackendView `json:"backend"`
PreserveHost bool `json:"preserve_host"`
Funnel bool `json:"funnel,omitempty"`
Warnings []WarningView `json:"warnings,omitempty"`
}
func ServiceViewFor ¶
func ServiceViewFor(svc registry.Service) ServiceView
func ServiceViews ¶
func ServiceViews(services []registry.Service) []ServiceView
type SummaryView ¶
type WarningCodeMeta ¶
Click to show internal directories.
Click to hide internal directories.