connectivity

package
v2.11.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package connectivity probes the network path between this machine and the endpoints the Kusari CLI needs.

Proxy configuration comes only from HTTP_PROXY/HTTPS_PROXY/NO_PROXY via http.ProxyFromEnvironment, so a passing check reflects what every other client in this CLI will do. There is deliberately no proxy flag.

Index

Constants

View Source
const (
	DefaultTimeout = 10 * time.Second
	SupportEmail   = "support@kusari.cloud"
)

Variables

This section is empty.

Functions

func ProxyLabel

func ProxyLabel(u *url.URL) string

ProxyLabel renders a proxy as host only, never credentials.

func ProxySummary

func ProxySummary(u *url.URL) string

ProxySummary renders a proxy URL with any password replaced.

func WriteReport

func WriteReport(path string, rep Report) error

WriteReport writes rep to path as indented JSON with owner-only permissions.

Types

type AllowlistHost

type AllowlistHost struct {
	Host    string `json:"host"`
	Purpose string `json:"purpose"`
}

AllowlistHost is a hostname a firewall or proxy allowlist needs.

func AllowlistHosts

func AllowlistHosts(targets []Target) []AllowlistHost

AllowlistHosts returns the hostnames to allow through a firewall or proxy.

type Category

type Category string

Category is a stable, machine-readable classification of a probe outcome.

const (
	CategoryOK       Category = "ok"
	CategoryDNS      Category = "dns"
	CategoryTCP      Category = "tcp"
	CategoryTLSTrust Category = "tls-trust"
	CategoryTLSOther Category = "tls-other"
	CategoryProxy    Category = "proxy"
	CategoryTimeout  Category = "timeout"
	CategoryUnknown  Category = "unknown"
)

type Diagnosis

type Diagnosis struct {
	Category    Category `json:"category"`
	Summary     string   `json:"summary"`
	Cause       string   `json:"cause,omitempty"`
	Remediation []string `json:"remediation,omitempty"`
	Raw         string   `json:"raw,omitempty"`
}

Diagnosis explains a probe failure in terms the user can act on.

func Classify

func Classify(cc classifyCtx, err error) Diagnosis

Classify turns a transport error into an actionable Diagnosis.

Ordering matters: a proxyconnect failure wraps the same *net.DNSError and *net.OpError as a direct failure, so it must match first or an unresolvable proxy gets reported as an unresolvable Kusari endpoint.

type Endpoints

type Endpoints struct {
	AuthURL     string
	PlatformURL string
	ConsoleURL  string
}

Endpoints holds the resolved base URLs to probe.

type Options

type Options struct {
	Timeout time.Duration
	// ProxyResolver defaults to http.ProxyFromEnvironment. Injectable because
	// net/http caches the proxy env behind a sync.Once, which makes
	// env-mutating tests order-dependent.
	ProxyResolver func(*http.Request) (*url.URL, error)
	UserAgent     string
}

Options configures a Check run.

type ProxyConfig

type ProxyConfig struct {
	HTTP    string `json:"http"`
	HTTPS   string `json:"https"`
	NoProxy string `json:"noProxy"`
}

ProxyConfig records the proxy environment with passwords redacted. Use forReport before serializing.

func ProxyEnvConfig

func ProxyEnvConfig(lookup func(string) string) ProxyConfig

ProxyEnvConfig reads the proxy environment, redacted. lookup is os.Getenv.

type ProxyConnectError

type ProxyConnectError struct {
	ProxyHost   string
	StatusCode  int
	Status      string
	AuthSchemes []string
}

ProxyConnectError reports a proxy that rejected CONNECT. net/http discards the status code and returns only the reason phrase, so we capture it here.

func (*ProxyConnectError) Error

func (e *ProxyConnectError) Error() string

type Report

type Report struct {
	SystemInfo SystemInfo      `json:"systemInfo"`
	Tests      []TestResult    `json:"tests"`
	Allowlist  []AllowlistHost `json:"allowlist"`
	Summary    Summary         `json:"summary"`
}

Report is the machine-readable result for a support ticket.

It is written expecting to leave the machine, so it discloses as little about the environment as the diagnostics allow: no hostname, no proxy credentials or usernames, and no NO_PROXY contents. This command loads no tokens, so there is no auth material to leak either.

func BuildReport

func BuildReport(results []Result, allowlist []AllowlistHost, cliVersion string, proxyEnv ProxyConfig, now time.Time) Report

BuildReport assembles a Report; now is injected so callers control the stamp.

type Result

type Result struct {
	Target     Target
	Proxy      *url.URL
	StatusCode int
	Status     string
	Location   string
	Duration   time.Duration
	TLS        *TLSInfo
	Diag       Diagnosis
	Err        error
}

Result is the outcome of probing one Target.

func Check

func Check(ctx context.Context, targets []Target, opts Options) []Result

Check probes every target concurrently and returns results in target order. Every failure is reported as a Result, so Check returns no error.

func (Result) OK

func (r Result) OK() bool

OK reports whether the endpoint is reachable: the TLS handshake completed and an HTTP status came back. 401, 403, 404, 3xx and 5xx all count.

func (Result) ServiceError

func (r Result) ServiceError() bool

ServiceError reports a 5xx: reachable, but the fault is Kusari's rather than the user's network.

type Summary

type Summary struct {
	Total  int `json:"total"`
	Passed int `json:"passed"`
	Failed int `json:"failed"`
}

type SystemInfo

type SystemInfo struct {
	OS         string      `json:"os"`
	Arch       string      `json:"arch"`
	CLIVersion string      `json:"cliVersion"`
	Timestamp  string      `json:"timestamp"`
	Proxy      ProxyConfig `json:"proxy"`
}

SystemInfo deliberately omits the hostname: corporate asset names commonly encode a person, department or site, and os/arch already cover the platform-specific diagnostics.

type TLSInfo

type TLSInfo struct {
	Version       string `json:"version"`
	CipherSuite   string `json:"cipherSuite"`
	PeerSubjectCN string `json:"peerSubjectCN,omitempty"`
	PeerIssuerCN  string `json:"peerIssuerCN,omitempty"`
}

TLSInfo records what the peer presented. Captured on success too: it reveals a trusted interception CA that would otherwise go unnoticed.

type Target

type Target struct {
	Name    string
	Purpose string
	URL     string
	// AllowAs, when set, replaces the URL's hostname in the allowlist output --
	// e.g. a wildcard covering every bucket on a shared S3 endpoint.
	AllowAs string
}

Target is one endpoint to probe.

func DefaultTargets

func DefaultTargets(e Endpoints) []Target

DefaultTargets returns the endpoints to probe, in display order.

Only one S3 bucket hostname is probed: S3 uses wildcard DNS and serves the same *.s3.<region>.amazonaws.com certificate for every bucket, so DNS, TCP, TLS and proxy egress verified against one bucket hold for all of them. The allowlist advertises the wildcard so proxy rules cover every upload bucket, including the tenant-specific ones.

type TestResult

type TestResult struct {
	Name          string   `json:"name"`
	Purpose       string   `json:"purpose"`
	URL           string   `json:"url"`
	Status        string   `json:"status"`
	StatusCode    int      `json:"statusCode,omitempty"`
	LatencyMs     int64    `json:"latencyMs"`
	Category      Category `json:"category"`
	Proxy         string   `json:"proxy,omitempty"`
	Authenticated bool     `json:"authenticated"`
	Error         string   `json:"error,omitempty"`
	TLS           *TLSInfo `json:"tls,omitempty"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL