appconfig

package
v0.1.35 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package appconfig owns the kafui-managed configuration document.

kafui deliberately never rewrites ~/.kaf/config (the kaf library's YAML round-trip strips TLS cert paths). This package is kafui's own home for settings the kaf schema cannot express — read-only flags, optional-integration endpoints, UI preferences, redaction rules — layered over the read-only kaf file.

Precedence (highest wins): CLI flags > kafui file > kaf file > defaults.

Index

Constants

View Source
const DefaultMetricsPollInterval = 5 * time.Second

DefaultMetricsPollInterval is the collector cadence used when a cluster's metrics config does not specify one. It is short so the metrics page shows live offset-delta rates quickly.

View Source
const MetricsTypeJMX = "JMX"

MetricsTypeJMX is the config value selecting JMX-over-Jolokia collection.

View Source
const MetricsTypePrometheus = "PROMETHEUS"

MetricsTypePrometheus is the default collection mechanism.

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath() string

DefaultPath returns the default kafui config path ($HOME/.config/kafui/config.yaml).

func Flatten

func Flatten(m map[string]any) map[string]string

Flatten turns a nested map into dot-separated keys, e.g. {"a": {"b": "c"}} becomes {"a.b": "c"}. Non-map leaves are stringified.

func Save

func Save(path string, cfg Config) error

Save writes the kafui-owned config to path, creating parent directories as needed. It ONLY ever writes the kafui file — never ~/.kaf/config. Fails (without writing) if the target is a directory or an existing file is not writable.

func Validate

func Validate(clusters []ClusterConfig) error

Validate checks the merged cluster list at startup:

  • a single unnamed cluster is assigned the name "default" (mutated in place)
  • multiple clusters require unique, non-empty names
  • every cluster must have at least one broker

Types

type AuditSettings

type AuditSettings struct {
	// Enabled turns auditing on. Default false ⇒ no records written.
	Enabled bool `yaml:"enabled"`
	// Level is "alter_only" (default) or "all". alter_only skips read-only ops.
	Level string `yaml:"level"`
	// Path overrides the audit log location (default ~/.kafui/audit.log).
	Path string `yaml:"path"`
}

AuditSettings configures the local audit log.

type AuthzSettings

type AuthzSettings struct {
	// ActiveProfile, when set, forces this profile as the active one regardless
	// of cluster membership (an explicit override).
	ActiveProfile string `yaml:"activeProfile"`

	// Profiles are the named permission profiles.
	Profiles []Profile `yaml:"profiles"`

	// Default is the fallback profile (permissions only, all clusters) applied
	// when no named profile covers the active cluster.
	Default *Profile `yaml:"default"`
}

AuthzSettings is the permission-profile configuration. Profiles collapse the spec's identity-bound roles to named profiles selected per cluster, since a local kafui has exactly one operator.

func (AuthzSettings) Enabled

func (a AuthzSettings) Enabled() bool

Enabled reports whether any profile or a default profile is configured. When disabled the Gate allows everything.

type AutoReloadSettings

type AutoReloadSettings struct {
	Enabled  bool          `yaml:"enabled"`
	Interval time.Duration `yaml:"interval"`
}

AutoReloadSettings control config-file hot-reloading (AC-16). Disabled by default. When enabled, kafui polls the config file's mtime every Interval and hot-applies reloadable settings (UI prefs, cluster extensions) — it never auto-reconnects the active cluster, only surfaces a notice.

type ClusterConfig

type ClusterConfig struct {
	Name    string
	Brokers []string
}

ClusterConfig is the minimal per-cluster view validation needs. It is built by merging the kaf clusters with kafui extensions (see merge.go).

type ClusterExtension

type ClusterExtension struct {
	ReadOnly bool `yaml:"readOnly"`

	// --- Fully-kafui-defined cluster connection (AC-13). Empty ⇒ overlay only. ---
	Brokers                []string    `yaml:"brokers,omitempty"`
	KafkaVersion           string      `yaml:"kafkaVersion,omitempty"`
	SecurityProtocol       string      `yaml:"securityProtocol,omitempty"`
	SASL                   *SASLConfig `yaml:"sasl,omitempty"`
	TLS                    *TLSConfig  `yaml:"tls,omitempty"`
	SchemaRegistryURL      string      `yaml:"schemaRegistryUrl,omitempty"`
	SchemaRegistryUsername string      `yaml:"schemaRegistryUsername,omitempty"`
	SchemaRegistryPassword string      `yaml:"schemaRegistryPassword,omitempty"`

	// PollingThrottle bounds background collection rate for this cluster.
	PollingThrottle time.Duration `yaml:"pollingThrottle"`

	// Connect lists Kafka Connect clusters for this Kafka cluster.
	Connect []ConnectCluster `yaml:"connect"`

	// Ksql is the ksqlDB endpoint config (optional).
	Ksql *KsqlEndpoint `yaml:"ksql"`

	// Metrics holds metrics-store settings (optional).
	Metrics map[string]string `yaml:"metrics"`

	// Masking holds data-masking rules for message payloads.
	Masking []string `yaml:"masking"`

	// Serdes holds per-cluster serde bindings (topic-name pattern → key/value
	// serde overrides). Unbound built-in serdes remain selectable regardless.
	Serdes []serde.SerdeConfig `yaml:"serdes"`

	// Properties are free-form custom client properties (dot-flattened on load).
	Properties         map[string]any `yaml:"properties"`
	ConsumerProperties map[string]any `yaml:"consumerProperties"`
	ProducerProperties map[string]any `yaml:"producerProperties"`
}

ClusterExtension carries per-cluster fields the kaf schema lacks.

When Brokers is non-empty the entry is a *fully kafui-defined* cluster (connection details live entirely in the kafui file, since ~/.kaf/config is read-only). When Brokers is empty the entry is an overlay attaching only the extra fields to a cluster defined in the kaf file. See IsFullyDefined.

func (ClusterExtension) IsFullyDefined

func (e ClusterExtension) IsFullyDefined() bool

IsFullyDefined reports whether this entry defines a cluster's connection entirely in the kafui file (as opposed to overlaying a kaf-file cluster).

func (ClusterExtension) MetricsSettings

func (e ClusterExtension) MetricsSettings() MetricsSettings

MetricsSettings returns the typed metrics settings for this cluster extension.

type Config

type Config struct {
	// DynamicConfigEnabled gates in-UI cluster editing (the setup wizard).
	DynamicConfigEnabled bool `yaml:"dynamicConfigEnabled"`

	// UI preferences persisted across runs.
	UI UISettings `yaml:"ui"`

	// ReleaseCheck controls the optional latest-release check.
	ReleaseCheck ReleaseCheckSettings `yaml:"releaseCheck"`

	// AutoReload controls hot-reloading of this config file while kafui runs.
	AutoReload AutoReloadSettings `yaml:"autoReload"`

	// Redaction controls secret masking in displayed configuration.
	Redaction RedactionSettings `yaml:"redaction"`

	// RefreshInterval is the background statistics collection cadence.
	RefreshInterval time.Duration `yaml:"refreshInterval"`

	// Clusters holds per-cluster extension entries keyed by cluster name.
	Clusters map[string]ClusterExtension `yaml:"clusters"`

	// Keybindings rebinds actions from the controls specification. Each entry
	// names a registry action and the keys that should trigger it; the first
	// key listed is the one shown in the hint bar and help overlay. Overrides
	// that conflict with another binding, shadow a reserved global, or use a
	// key terminals cannot report are reported and ignored.
	Keybindings []KeybindingOverride `yaml:"keybindings"`

	// Authz holds the local permission-profile configuration (AA-2). A missing
	// section (no profiles and no default) leaves authorization disabled: every
	// operation is allowed. Read-only mode is independent of this section.
	Authz AuthzSettings `yaml:"authz"`

	// Audit configures the local JSONL audit log (AA-6). Disabled by default.
	Audit AuditSettings `yaml:"audit"`
}

Config is the kafui-owned configuration document (loaded from config.yaml).

func ApplyCluster

func ApplyCluster(path string, running Config, originalName, name string, ext ClusterExtension) (Config, error)

ApplyCluster merges a cluster into the running config (replacing originalName on rename, otherwise inserting/replacing by name), structurally validates the result, and persists ONLY the kafui-owned file at path. On any error the running config is returned unchanged and nothing is written. On success it returns the new effective config.

func Default

func Default() Config

Default returns a Config populated with sensible defaults (used when no file exists).

func DeleteCluster

func DeleteCluster(path string, running Config, name string) (Config, error)

DeleteCluster removes a cluster from the running config and persists ONLY the kafui file. On any error the running config is returned unchanged.

func Load

func Load(path string) (Config, error)

Load reads the kafui config from path. A missing file is not an error: it returns defaults with a nil error (per "Missing dynamic config file tolerated"). A present-but-malformed file is a hard error.

type ConnectCluster

type ConnectCluster struct {
	Name                string `yaml:"name"`
	Address             string `yaml:"address"`
	Username            string `yaml:"username"`
	Password            string `yaml:"password"`
	TLSCAPath           string `yaml:"tlsCaPath"`
	TLSCertPath         string `yaml:"tlsCertPath"`
	TLSKeyPath          string `yaml:"tlsKeyPath"`
	ConsumerNamePattern string `yaml:"consumerNamePattern"`
}

ConnectCluster describes one Kafka Connect cluster.

type KeybindingOverride added in v0.1.35

type KeybindingOverride struct {
	// Action is the registry action id, e.g. "delete" or "actions-menu".
	Action string `yaml:"action"`
	// Keys are the keys that trigger it, most-advertised first.
	Keys []string `yaml:"keys"`
}

KeybindingOverride rebinds one action declared in the controls specification.

type KsqlEndpoint

type KsqlEndpoint struct {
	URL              string `yaml:"url"`
	Username         string `yaml:"username"`
	Password         string `yaml:"password"`
	TLSCAPath        string `yaml:"tlsCaPath"`
	TLSCertPath      string `yaml:"tlsCertPath"`
	TLSKeyPath       string `yaml:"tlsKeyPath"`
	MaxResponseBytes int64  `yaml:"maxResponseBytes"`
}

KsqlEndpoint describes a ksqlDB endpoint. URL may be a comma-separated list of endpoints for connection-level failover. MaxResponseBytes caps the response read size (0 ⇒ the client's 20 MB default).

func (KsqlEndpoint) String

func (k KsqlEndpoint) String() string

String renders the endpoint with the password redacted so it is safe to log.

type MetricsSettings

type MetricsSettings struct {
	// Enabled reports whether metrics collection is switched on. It defaults to
	// true: offset-delta metrics cost little and are always useful.
	Enabled bool
	// PollInterval is the background collection cadence (0 ⇒ collector default).
	PollInterval time.Duration
	// Endpoint is an optional Prometheus/JMX-exporter metrics URL. Empty means
	// offset-delta-only collection (byte rates reported as unknown).
	Endpoint string
	// Type selects the collection mechanism: "PROMETHEUS" (default) scrapes the
	// exposition endpoint; "JMX" is honored only through a Jolokia HTTP bridge
	// (JolokiaURL) and otherwise degrades to a warning and empty broker metrics
	// (MM-17). Stored upper-cased.
	Type string
	// JolokiaURL is the optional Jolokia HTTP-bridge base URL used when Type is
	// "JMX" (MM-17). Empty ⇒ JMX degrades gracefully.
	JolokiaURL string
	// Username/Password are optional basic-auth credentials for scraping and the
	// Jolokia bridge.
	Username string
	Password string
	// TimeSeriesURLs is the optional list of Prometheus-compatible query API base
	// URLs used for range/instant graphs (MM-14/MM-15). Empty ⇒ no graph backend.
	TimeSeriesURLs []string
	// TLSCAPath is an optional custom CA PEM path for the query/scrape HTTPS
	// clients.
	TLSCAPath string
	// ExpositionEnabled opts a cluster in to the flag-gated Prometheus exposition
	// endpoint (MM-16). Defaults to true so an unset value still exports.
	ExpositionEnabled bool
}

MetricsSettings is the typed view of a cluster's optional metrics configuration, parsed from the free-form ClusterExtension.Metrics map (kept as a map for forward-compatibility with the application-config schema).

Offset-delta metrics (message-in rates) are always available regardless of this config. Endpoint is only needed for byte-rate scraping / range graphs, which are a documented stub in this build.

func ParseMetricsSettings

func ParseMetricsSettings(m map[string]string) MetricsSettings

ParseMetricsSettings turns the free-form metrics map into typed settings, applying defaults for absent keys. Recognized keys (case-insensitive):

enable/enabled       bool   (default true)
pollInterval/interval duration string, e.g. "10s" (default DefaultMetricsPollInterval)
endpoint/url         string (default "")

type Permission

type Permission struct {
	Resource string   `yaml:"resource"`
	Name     string   `yaml:"name"`
	Actions  []string `yaml:"actions"`
}

Permission grants a set of actions on a resource type, optionally narrowed to resource names matching Name (a regex, full-match). An empty Name matches any resource of the type.

type Profile

type Profile struct {
	Name        string       `yaml:"name"`
	Clusters    []string     `yaml:"clusters"`
	Permissions []Permission `yaml:"permissions"`
}

Profile is a named set of permissions scoped to one or more clusters.

type RedactionSettings

type RedactionSettings struct {
	Enabled  bool     `yaml:"enabled"`
	Patterns []string `yaml:"patterns"` // when non-empty, replaces the default pattern list
}

RedactionSettings control secret masking.

type Redactor

type Redactor struct {
	// contains filtered or unexported fields
}

Redactor masks secret values in displayed configuration.

func NewRedactor

func NewRedactor(s RedactionSettings) *Redactor

NewRedactor builds a Redactor from settings. When s.Patterns is set it fully replaces the defaults; a glob-ish "ssl.*password" is treated as a substring regex where "*" means ".*".

func (*Redactor) Redact

func (r *Redactor) Redact(key, value string) string

Redact returns the value masked when key matches a secret pattern. Externalized ${provider:...} references pass through unmasked.

type ReleaseCheckSettings

type ReleaseCheckSettings struct {
	Enabled  bool          `yaml:"enabled"`
	Interval time.Duration `yaml:"interval"`
	Timeout  time.Duration `yaml:"timeout"`
}

ReleaseCheckSettings control the GitHub latest-release check.

type SASLConfig

type SASLConfig struct {
	Mechanism    string `yaml:"mechanism"`
	Username     string `yaml:"username"`
	Password     string `yaml:"password"`
	ClientID     string `yaml:"clientID"`
	ClientSecret string `yaml:"clientSecret"`
	TokenURL     string `yaml:"tokenURL"`
	// DeviceAuthURL is the OAuth2 device-authorization endpoint. When set (with a
	// ClientID and TokenURL but no ClientSecret or static Token), kafui runs the
	// interactive device-code grant for OAUTHBEARER (AA-13).
	DeviceAuthURL string `yaml:"deviceAuthURL"`
}

SASLConfig is the broker SASL authentication for a fully-kafui-defined cluster. Mechanism is one of PLAIN, SCRAM-SHA-256, SCRAM-SHA-512, OAUTHBEARER.

type TLSConfig

type TLSConfig struct {
	CAPath   string `yaml:"caPath"`
	CertPath string `yaml:"certPath"`
	KeyPath  string `yaml:"keyPath"`
	Insecure bool   `yaml:"insecure"`
}

TLSConfig is the broker TLS material (PEM file paths) for a fully-kafui-defined cluster.

type UISettings

type UISettings struct {
	Theme       string `yaml:"theme"` // "auto", "dark", "light"
	ShowSidebar bool   `yaml:"showSidebar"`
	CompactMode bool   `yaml:"compactMode"`
	Timezone    string `yaml:"timezone"` // "local", "UTC", or an IANA name
}

UISettings are persisted UI preferences.

type ValidationError

type ValidationError struct {
	Field   string
	Cluster string
	Message string
}

ValidationError describes a startup configuration problem.

func (ValidationError) Error

func (e ValidationError) Error() string

Jump to

Keyboard shortcuts

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