k8s

package
v1.7.2 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: GPL-3.0 Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const (
	HelmDocManifest     = "manifest"
	HelmDocNotes        = "notes"
	HelmDocUserValues   = "user values"
	HelmDocMergedValues = "merged values"
	HelmDocHooks        = "hooks"
)

Helm document kinds surfaced as Relatives Info rows. The Label string is what shows on the row and is also how the UI dispatches Y → helm CLI fetch (no extra metadata on RelativeRow needed). Keep in sync with IsHelmDocLabel below.

Variables

View Source
var DefaultRegistry = NewRegistry()

DefaultRegistry is the global registry initialized with built-in resources.

Functions

func ContainerNames

func ContainerNames(raw interface{}) []string

ContainerNames extracts container names (init + regular) from a Pod's Raw field. Returns nil if the Raw field is not a *corev1.Pod.

func DiscoverCRDs

func DiscoverCRDs(ctx context.Context, client *Client) (int, error)

DiscoverCRDs queries the API server for CustomResourceDefinitions and registers each one into the client's registry under the "Custom Resources" category. Only CRDs with a served+storage version are registered.

func EnrichRelatives added in v1.4.0

func EnrichRelatives(ctx context.Context, cs kubernetes.Interface, rt ResourceType, item ResourceItem, detail *ResourceDetail)

EnrichRelatives fills in kind-specific Relatives data that requires an API call (selector → pod resolution, owner chains, endpoint slices, ...). The synchronous Detailer can't do this because it has no clientset; the caller (ui.fetchResourceDetail) invokes EnrichRelatives after the detailer returns. Quiet on error — the Relatives tab simply shows fewer entries.

func FetchChildResources

func FetchChildResources(ctx context.Context, clientset kubernetes.Interface, parentType ResourceType, item ResourceItem) (ResourceType, []ResourceItem, error)

FetchChildResources fetches child resources for a parent via the registry's DrillDown config.

func FetchHelmDoc added in v1.5.0

func FetchHelmDoc(ctx context.Context, label, releaseName, namespace string) (string, error)

FetchHelmDoc shells out to `helm get <subcommand> <release> -n <ns>` for the given document label. Returns the raw stdout. The caller decides how to render it (manifest/values/hooks are YAML; notes is plain text — both go through the same YAML popup since notes still reads fine in monospace).

func FormatHelmHistoryDate added in v1.5.0

func FormatHelmHistoryDate(s string) string

FormatHelmHistoryDate converts the RFC3339 timestamp in ReleaseRevision.Updated into the same age string the rest of km8 uses (e.g. "5d", "12h"). Falls back to the raw string when parsing fails so users still see something rather than an empty cell.

func HelmAvailable added in v1.5.0

func HelmAvailable() bool

HelmAvailable reports whether the `helm` CLI was detected at startup. Result is cached after the first detection call.

func HelmHideManaged added in v1.5.1

func HelmHideManaged() bool

HelmHideManaged reports whether the global helm-managed filter is on.

func HelmIcon added in v1.5.1

func HelmIcon() string

HelmIcon returns the popup-title glyph U+F0833 (Nerd Font ship's wheel from the Material Design family). Picked over standard Unicode ⎈ (U+2388) because every other km8 popup title icon (context / namespace / yamlpopup / settings / ...) is in the same NF Material Design range — the Unicode helm symbol renders ~half the optical height in JetBrains Mono and read as an outlier next to the other popup icons. NF is already km8's baseline icon design, so falling back to standard Unicode for one popup didn't buy any portability the rest of the surface didn't already lack.

func HelmRowMark added in v1.5.1

func HelmRowMark() string

HelmRowMark returns the panel 2 row marker for helm-managed items. Same glyph as HelmIcon so the helm-managed signal stays visually consistent between the per-row mark and the popup title. NF is already km8's baseline icon design — a row-marker fallback box on non-NF terminals is no worse than the kind icons already broken in those same terminals.

func IsHelmDocLabel added in v1.5.0

func IsHelmDocLabel(label string) bool

IsHelmDocLabel reports whether a RelativeRow.Label corresponds to one of the five Helm Info documents. Used by the UI to decide whether Y goes through the helm CLI path vs. the default kubectl-yaml path.

func IsHelmManaged added in v1.5.0

func IsHelmManaged(item ResourceItem) bool

IsHelmManaged reports whether a K8s resource was created by Helm. Detection matches kubectl's own heuristic: either the `app.kubernetes.io/managed-by` label set to "Helm" or the `meta.helm.sh/release-name` annotation set by the helm renderer. Both are reliable post-helm-v3.

func IsHelmStorageSecret added in v1.5.0

func IsHelmStorageSecret(item ResourceItem) bool

IsHelmStorageSecret reports whether a Secret is one of helm's per-revision release storage blobs (`type: helm.sh/release.v1`). These dominate the Secrets list in any cluster running helm — useful by themselves, but usually just noise relative to the real workload secrets users want to inspect.

func MarkHelm added in v1.5.1

func MarkHelm(item ResourceItem) string

MarkHelm returns the helm row marker when the item is helm-managed (either by label/annotation, or — for Secrets — as a helm storage blob), else "". Used as the cell value for the unlabeled marker column right after Name on every resource type.

func MarshalContainerYAML added in v1.0.7

func MarshalContainerYAML(item ResourceItem, containerName string) string

MarshalContainerYAML extracts a single container's spec and status from the parent Pod (wrapped in item.Raw) and returns them as a YAML document. Returns empty string when item is not a Pod or the container is not found.

func MarshalItemYAML added in v1.0.7

func MarshalItemYAML(item ResourceItem) string

MarshalItemYAML returns a YAML representation of a resource item for the detail panel. ManagedFields are stripped for readability (matching kubectl's default behavior since 1.21). Returns an empty string when the item's Raw payload cannot be marshaled — callers should fall back to structured detail.

func MarshalItemYAMLForCompare added in v1.6.0

func MarshalItemYAMLForCompare(item ResourceItem) string

MarshalItemYAMLForCompare returns the YAML representation of a resource item suitable for a diff against another instance of the same kind. Strips fields that are intrinsically per-instance noise:

  • .status entirely — Kubernetes reconciles config → status, so any legitimate config drift will surface on the next reconcile and status drift between two reconciled resources is just churn.
  • .metadata.managedFields — server-side apply bookkeeping; the same value would never line up between two instances.
  • .metadata.resourceVersion, .uid, .creationTimestamp, .generation — bookkeeping that increments / is unique per instance and writes noise into every diff.

Caller-controlled choice (not stripped here): namespace + name — those are the IDENTITY of each instance; surfacing them in the diff lets the user verify which side is which.

func PodStatus added in v1.2.0

func PodStatus(p *corev1.Pod) string

PodStatus returns the human-visible status string for a pod — matching the STATUS column of `kubectl get pods`. The bare Pod.Status.Phase misses common transient states because the Phase stays "Running" while individual containers are in CrashLoopBackOff / ImagePullBackOff / etc.; this walks container statuses to pull out the reason kubectl would display.

func RegisterHelmIfAvailable added in v1.5.0

func RegisterHelmIfAvailable()

RegisterHelmIfAvailable probes for the `helm` CLI on PATH and, if found, registers the ResourceReleases definition into DefaultRegistry. Safe to call multiple times — detection runs once.

func RollbackCommandString added in v1.5.0

func RollbackCommandString(releaseName, namespace string, revision int) string

RollbackCommandString returns the exact shell command that RollbackRelease will execute, suitable for showing in a confirm popup so the user sees what's about to run.

func RollbackRelease added in v1.5.0

func RollbackRelease(ctx context.Context, releaseName, namespace string, revision int) (string, error)

RollbackRelease runs `helm rollback <rel> <rev> -n <ns>` and returns the helm CLI's stdout (typically "Rollback was a success! Happy Helming!"). Errors propagate from helm — caller should surface them to app log.

func SetHelmHideManaged added in v1.5.1

func SetHelmHideManaged(v bool)

SetHelmHideManaged sets the global filter state.

func SortItems added in v1.6.0

func SortItems(items []ResourceItem, columns []Column, columnTitle string, ascending bool)

SortItems sorts items in place by a single column. Thin wrapper over SortItemsChain — kept for callers that haven't migrated yet and for the test surface where single-column is the natural case.

func SortItemsChain added in v1.7.0

func SortItemsChain(items []ResourceItem, columns []Column, tiers []SortTier)

SortItemsChain sorts items in place by the ordered tier list. Tier 0 is the primary sort, tier 1 the first tiebreaker, and so on. A tier whose Column doesn't match any of the kind's columns is silently skipped (defensive against stale config). Empty chain, or a chain where every tier is unknown / non-discriminating, degrades to the stable sort's natural fallback (incoming order).

Comparator dispatch is per-tier — Age uses the time comparator, Ready parses N/M, etc. — so mixing typed tiers (e.g. Restarts desc + Age asc) works without per-call configuration.

func ToggleHelmHideManaged added in v1.5.1

func ToggleHelmHideManaged() bool

ToggleHelmHideManaged flips the filter and returns the new value.

Types

type CategoryGroup

type CategoryGroup struct {
	Label     string
	Order     int
	Resources []ResourceDefinition
}

CategoryGroup represents a sidebar category with its resources.

type ChildFetcher

type ChildFetcher func(ctx context.Context, clientset kubernetes.Interface, item ResourceItem) ([]ResourceItem, error)

ChildFetcher fetches child resources for drill-down.

type ChildTypeResolver added in v1.0.9

type ChildTypeResolver func(item ResourceItem) ResourceType

ChildTypeResolver returns the ResourceType of children produced for a given parent item. Per-item resolution lets a single drill-down config produce different child types depending on what the parent points at (e.g. HPA drilling down to Deployment vs StatefulSet vs DaemonSet). Returning "" is allowed; FetchChildren should return an empty list / error in that case.

func StaticChildType added in v1.0.9

func StaticChildType(t ResourceType) ChildTypeResolver

StaticChildType is a ChildTypeResolver that always returns the same type — used for drill-downs whose child type doesn't depend on the parent item.

type Client

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

Client wraps a Kubernetes clientset and tracks the current context and namespace filter. It is the primary entry point for all cluster operations in km8.

func NewClient

func NewClient(contextName string) (*Client, error)

NewClient creates a Client for the given context name. If contextName is empty, the current-context from the kubeconfig is used. The kubeconfig location is resolved via $KUBECONFIG, falling back to ~/.kube/config.

func (*Client) Clientset

func (c *Client) Clientset() kubernetes.Interface

Clientset returns the underlying Kubernetes clientset.

func (*Client) ContextName

func (c *Client) ContextName() string

ContextName returns the name of the active kubeconfig context.

func (*Client) DynamicClient

func (c *Client) DynamicClient() dynamic.Interface

DynamicClient returns the dynamic Kubernetes client for CRD access.

func (*Client) GetClusterInfo

func (c *Client) GetClusterInfo() ClusterInfo

GetClusterInfo returns metadata about the currently connected cluster.

func (*Client) GetNamespace

func (c *Client) GetNamespace() string

GetNamespace returns the current namespace filter. An empty string means all namespaces.

func (*Client) ListContexts

func (c *Client) ListContexts() []string

ListContexts returns all context names available in the kubeconfig.

func (*Client) Registry

func (c *Client) Registry() *Registry

Registry returns the resource registry associated with this client.

func (*Client) RestConfig

func (c *Client) RestConfig() *rest.Config

RestConfig returns the REST config used to connect to the cluster.

func (*Client) SetNamespace

func (c *Client) SetNamespace(ns string)

SetNamespace sets the namespace filter. An empty string means all namespaces.

type ClusterInfo

type ClusterInfo struct {
	ContextName string
	ClusterName string
	ServerURL   string
	Namespace   string
}

ClusterInfo holds metadata about the currently connected Kubernetes cluster.

type Column

type Column struct {
	Title    string
	MinWidth int
}

Column defines a table column with a title and minimum width.

type ConditionItem added in v1.5.5

type ConditionItem struct {
	Type    string // e.g. "Ready", "PodScheduled", "Available"
	Status  string // "True" | "False" | "Unknown"
	Reason  string // brief CamelCase reason
	Message string // human-readable message
	Age     string // since LastTransitionTime
}

ConditionItem holds one row of a resource's .status.conditions for display on the Conditions tab. Mirrors what `kubectl describe` shows in its Conditions section: type / status / reason / message + age since last transition. Populated by ExtractConditions for kinds that carry conditions (Pod, Deployment, StatefulSet, ...); nil for kinds without (ConfigMap, Secret, etc.) — the Conditions tab is hidden when this slice is empty.

func ExtractConditions added in v1.5.5

func ExtractConditions(item ResourceItem) []ConditionItem

ExtractConditions returns the resource's .status.conditions as a flat []ConditionItem ready for display. Returns nil for kinds without conditions or when item.Raw doesn't match a supported type.

Supported kinds: Pod, Node, PersistentVolumeClaim, Deployment, StatefulSet, DaemonSet, ReplicaSet, Job, HorizontalPodAutoscaler, Ingress.

All other kinds (ConfigMap, Secret, Service, ServiceAccount, Role, ...) return nil and the Conditions tab will not appear for them.

type ContainerInfo

type ContainerInfo struct {
	Name     string
	Image    string
	State    string
	Ready    bool
	Restarts int
	Ports    string
	Init     bool
}

ContainerInfo holds detail about a single container in a Pod.

type DetailField

type DetailField struct {
	Label string
	Value string
}

DetailField is a key-value pair for resource-specific detail.

type DrillDownConfig

type DrillDownConfig struct {
	ChildTypeFor  ChildTypeResolver
	FetchChildren ChildFetcher
}

DrillDownConfig defines drill-down behavior for a resource type.

type EventItem

type EventItem struct {
	Type    string
	Reason  string
	Object  string
	Message string
	Age     string
}

EventItem holds a single event for display.

func FetchResourceEvents

func FetchResourceEvents(ctx context.Context, clientset kubernetes.Interface, name, namespace string) ([]EventItem, error)

FetchResourceEvents fetches events related to a specific resource by name, optionally filtering by namespace. Events are returned sorted by last timestamp, newest first.

func FetchResourceEventsAggregated added in v1.5.5

func FetchResourceEventsAggregated(ctx context.Context, clientset kubernetes.Interface, item ResourceItem) ([]EventItem, error)

FetchResourceEventsAggregated returns events for the resource AND its child pods when the resource is a workload that PodsForWorkload supports (Deployment today). For other kinds it falls back to single-object behavior (parent events only). All events are merged and sorted by timestamp, newest first.

Rationale: kubectl describe of a Deployment shows only the Deployment's own events, which are sparse (ScalingReplicaSet only). The interesting events during a rollout / outage are on the child Pods (BackOff, ImagePullBackOff, Killing). km8 aggregates them so the Events tab is useful one level up, mirroring the aggregate-logs pattern.

type LogLine

type LogLine struct {
	StreamID  int64
	Pod       string
	Container string
	Text      string
}

LogLine represents a single log line from a container.

StreamID tags the line with the LogStreamer epoch that emitted it. Consumers compare against LogStreamer.CurrentStreamID() to drop stale lines from a closed prior stream — buffered residue in the channel can still be received with ok=true after Stop closed it (Go closed-buffered-channel semantics), and without the tag those lines would bleed into the next stream's detail panel.

type LogStreamer

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

LogStreamer streams logs from one or more containers in a pod. It integrates with Bubble Tea through a channel-based message pattern.

aggregate distinguishes single-pod streams (Start: Pod identity is implicit — the user is on the Pod's detail panel) from multi-pod aggregate streams (StartMulti: pods come from a workload's selector and every line needs a Pod tag so the consumer can colour-code by source). When aggregate=false, emitted LogLine.Pod is left empty so the renderer skips the `<pod-hash>@` prefix segment.

Channel lifecycle: each Start allocates a fresh lines channel + wg; Stop synchronously waits for producers (they exit promptly after ctx cancel propagates to k8s.Stream) and CLOSES the channel. Parked readers (the consumer-side waitForLogLine Cmd) unblock with !ok and return nil, ending the chain cleanly — without close, each Stop + Start leaked one parked reader per row change because the consumer was still blocked on the OLD shared channel.

func NewLogStreamer

func NewLogStreamer(clientset kubernetes.Interface) *LogStreamer

NewLogStreamer creates a new LogStreamer for the given clientset. The lines channel is left nil — start() allocates it on first Start, Stop closes and nils it. Keeps the lifecycle invariant uniform: Lines() returns non-nil only while a stream is active. The previous eager `make(chan LogLine, 64)` here was dead (start always overwrote it) and contradicted Lines()'s nil-after-Stop docstring; waitForLogLine has a nil-channel guard so the pre- first-Start state is handled cleanly.

func (*LogStreamer) CurrentStreamID added in v1.7.2

func (ls *LogStreamer) CurrentStreamID() int64

CurrentStreamID returns the active stream's epoch — the value producers tagged their LogLine emissions with. The Update-side LogLineMsg handler compares msg.StreamID against this to drop stale buffered residue from a prior stream.

func (*LogStreamer) Lines

func (ls *LogStreamer) Lines() <-chan LogLine

Lines returns the channel for receiving log lines. Returns nil before the first Start and after every Stop (the field is nil-ed during stopLocked alongside the close). In practice the consumer captures the channel at waitForLogLine dispatch time: a stopped stream's channel was closed before nil-ing here, so the consumer unblocks with !ok cleanly; a not-yet-started streamer returns nil and waitForLogLine's nil-channel guard returns a nil Cmd without spawning a goroutine.

func (*LogStreamer) Start

func (ls *LogStreamer) Start(podName, namespace string, containers []string)

Start streams the named containers from a single pod. LogLine.Pod is left empty on emitted lines so the renderer drops the `<pod-hash>@` prefix segment (pod identity is implicit when the user is on Pod detail).

func (*LogStreamer) StartMulti added in v1.3.0

func (ls *LogStreamer) StartMulti(targets []PodTarget)

StartMulti cancels any existing stream and starts streaming logs from every (pod, container) pair in `targets`. All lines flow through the shared Lines() channel; each LogLine carries Pod / Container / Text so the consumer can multiplex by either dimension.

func (*LogStreamer) Stop

func (ls *LogStreamer) Stop()

Stop cancels the current log stream, waits for in-flight producer goroutines to exit (they exit promptly after ctx cancel propagates to the k8s Stream → scanner.Scan returns false), then closes the lines channel so any parked consumer (waitForLogLine) unblocks with !ok and returns nil.

Blocks the caller for the duration of producer drain — typically milliseconds (scanner.Scan returns immediately when the underlying HTTP body is closed by ctx cancel). Synchronous wait is the cost of correctness: without it, closing the channel concurrently with producers' `case lines <- ...:` would panic.

type PodRelativesData added in v1.4.0

type PodRelativesData struct {
	Owner          *RefTarget
	Node           *RefTarget // cluster-scoped
	ServiceAccount *RefTarget
	Volumes        []VolumeRef
	Images         []string
	InitImages     []string
}

PodRelativesData is the structured "Relatives" content for a Pod.

Owner is the immediate K8s owner reference (ReplicaSet / DaemonSet / StatefulSet / Job). Drilling further (RS → Deployment) is left to follow-up commits — for MVP we surface the one-hop owner only.

Volumes lists the Pod's spec.volumes with their source kind and an optional drill ref (ConfigMap / Secret / PVC sources are drillable; emptyDir / hostPath / projected / downwardAPI are informational).

Images carries the rendered image strings (e.g. "nginx:1.27.1") for informational display — there's no K8s resource to drill into for an image.

type PodTarget added in v1.3.0

type PodTarget struct {
	Name       string
	Namespace  string
	Containers []string
}

PodTarget identifies a pod whose containers should be streamed. Used by LogStreamer.StartMulti to aggregate logs across multiple pods (e.g. all pods of a Deployment's current ReplicaSet).

func PodsForCronJob added in v1.5.5

func PodsForCronJob(ctx context.Context, cs kubernetes.Interface, cj *batchv1.CronJob) ([]PodTarget, error)

PodsForCronJob walks the 2-hop chain CronJob → Jobs → Pods. Returns Pods from every Job currently retained by the CronJob (K8s history limits usually keep ≤4 Jobs: successfulJobsHistoryLimit default 3 + active + failedJobsHistoryLimit default 1). All retained Jobs' Pods are included so past runs are visible for "why did last night's job fail" debug.

func PodsForDaemonSet added in v1.5.5

func PodsForDaemonSet(ctx context.Context, cs kubernetes.Interface, ds *appsv1.DaemonSet) ([]PodTarget, error)

PodsForDaemonSet returns Pods matching the DaemonSet's selector (one Pod per matching Node). Returns empty slice when no Pods match.

func PodsForDeployment added in v1.3.0

func PodsForDeployment(ctx context.Context, cs kubernetes.Interface, dep *appsv1.Deployment, currentOnly bool) ([]PodTarget, error)

PodsForDeployment resolves a Deployment to the list of pod targets whose containers should be streamed for aggregate logs.

When currentOnly is true, only pods belonging to the Deployment's *current* ReplicaSet (matched via the `deployment.kubernetes.io/revision` annotation) are returned — i.e. the live generation, excluding rollout leftovers. When false, all pods matching the Deployment's selector are returned (useful for observing both old and new pods during a rollout).

Falls back to selector-only matching if the current-RS lookup fails (RBAC missing on ReplicaSet, etc.). Returns an empty slice when no pods match — callers should treat that as "no pods running" rather than an error.

func PodsForJob added in v1.5.5

func PodsForJob(ctx context.Context, cs kubernetes.Interface, job *batchv1.Job) ([]PodTarget, error)

PodsForJob returns Pods owned by the Job. Uses the `job-name=<jobName>` label rather than spec.Selector because Job's auto-generated selector (with controller-uid) is opaque and the job-name label is the standard kubectl idiom (`kubectl logs job/X` works the same way).

func PodsForReplicaSet added in v1.5.5

func PodsForReplicaSet(ctx context.Context, cs kubernetes.Interface, rs *appsv1.ReplicaSet) ([]PodTarget, error)

PodsForReplicaSet returns Pods matching the ReplicaSet's selector. Used when the user drills into an RS from Deployment's Relatives — surfacing just this RS's Pods (vs. all of the Deployment's selector).

func PodsForStatefulSet added in v1.5.5

func PodsForStatefulSet(ctx context.Context, cs kubernetes.Interface, ss *appsv1.StatefulSet) ([]PodTarget, error)

PodsForStatefulSet returns Pods matching the StatefulSet's selector. No revision filter — StatefulSets don't track revisions on Pods at the selector level. Returns empty slice when no Pods match (not an error).

func PodsForWorkload added in v1.3.0

func PodsForWorkload(ctx context.Context, cs kubernetes.Interface, item ResourceItem, currentOnly bool) ([]PodTarget, error)

PodsForWorkload dispatches to the right kind-specific resolver for the workload's live Pods. Used by both aggregate logs and aggregate events.

Supported kinds: Deployment, StatefulSet, DaemonSet, Job, ReplicaSet, CronJob.

currentOnly only applies to Deployment (filters to its current ReplicaSet's Pods, ignoring rollout leftovers). Other kinds don't have a revision model, so currentOnly is ignored and all matching Pods are returned. CronJob returns Pods from all currently-retained Jobs (bounded by K8s history limits, typically ≤4).

Keeps the ui package free of apps/v1 / batchv1 imports.

type RefTarget added in v1.3.0

type RefTarget struct {
	Type      ResourceType
	Name      string
	Namespace string
}

RefTarget identifies another Kubernetes resource that the Relatives tab can drill into. Type is the km8 ResourceType (Pod, Secret, ConfigMap, Node, ...); Namespace is empty for cluster-scoped kinds.

type Registry

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

Registry holds all registered resource definitions.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty registry.

func (*Registry) AllTypes

func (r *Registry) AllTypes() []ResourceType

AllTypes returns all registered resource types in sidebar display order.

func (*Registry) ClearDynamic

func (r *Registry) ClearDynamic()

ClearDynamic removes all dynamically registered (CRD) resource definitions.

func (*Registry) ColumnsFor

func (r *Registry) ColumnsFor(rt ResourceType) []Column

ColumnsFor returns the column definitions for a resource type.

func (*Registry) FetchResources

func (r *Registry) FetchResources(ctx context.Context, clientset kubernetes.Interface, rt ResourceType, namespace string) ([]ResourceItem, error)

FetchResources fetches resources using the registered fetcher.

func (*Registry) Get

Get returns the definition for a resource type, or nil if not found.

func (*Registry) GetResourceDetail

func (r *Registry) GetResourceDetail(rt ResourceType, item ResourceItem) ResourceDetail

GetResourceDetail extracts detail using the registered detailer.

func (*Registry) LookupByKubectlName added in v1.6.0

func (r *Registry) LookupByKubectlName(name string) ResourceType

LookupByKubectlName resolves a kubectl short-name (e.g. "pod", "configmap", "namespace") to the registered ResourceType. Returns the empty ResourceType if no match. Used to resolve user-editable strings in the config file (e.g. PinnedResourceKinds entries) into runtime ResourceTypes.

func (*Registry) Register

func (r *Registry) Register(def *ResourceDefinition)

Register adds a resource definition to the registry.

func (*Registry) SidebarCategories

func (r *Registry) SidebarCategories() []CategoryGroup

SidebarCategories returns resource definitions grouped by category, sorted.

func (*Registry) StartWatch

func (r *Registry) StartWatch(ctx context.Context, clientset kubernetes.Interface, rt ResourceType, namespace string) (watch.Interface, error)

StartWatch starts a watch using the registered WatchStarter.

func (*Registry) Unregister

func (r *Registry) Unregister(rt ResourceType)

Unregister removes a resource definition from the registry.

type RelativeRow added in v1.4.0

type RelativeRow struct {
	Label string
	Value string
	Ref   *RefTarget
}

RelativeRow is one row inside a RelativeSection. Display format is "Label Value [→]" — the arrow appears when Ref is non-nil.

type RelativeSection added in v1.4.0

type RelativeSection struct {
	Title   string
	Entries []RelativeRow
}

RelativeSection is one labeled group of link rows on the Relatives tab. Title is the header label (empty title renders no header row). Entries with a non-nil Ref are drillable; entries with Ref==nil are informational text.

type Release added in v1.5.0

type Release struct {
	Name       string `json:"name"`
	Namespace  string `json:"namespace"`
	Revision   string `json:"revision"`
	Updated    string `json:"updated"`
	Status     string `json:"status"`
	Chart      string `json:"chart"`
	AppVersion string `json:"app_version"`
}

Release is the parsed shape of one entry from `helm list -o json`. Field names match the helm CLI's JSON output verbatim.

type ReleaseRevision added in v1.5.0

type ReleaseRevision struct {
	Revision    int    `json:"revision"`
	Updated     string `json:"updated"` // RFC3339 with offset (different from helm list's Go time.String)
	Status      string `json:"status"`
	Chart       string `json:"chart"`
	AppVersion  string `json:"app_version"`
	Description string `json:"description"`
}

ReleaseRevision is the parsed shape of one entry from `helm history <rel> -o json`. Note `revision` is JSON-numeric here even though `helm list -o json` reports it as a string — keep the int type rather than fight the helm CLI's inconsistency.

type ResourceDefinition

type ResourceDefinition struct {
	Type            ResourceType
	DisplayName     string
	KubectlName     string
	Category        string
	CategoryOrder   int // lower = higher in sidebar
	OrderInCategory int // position within category
	ClusterScoped   bool
	Columns         []Column
	Fetcher         ResourceFetcher
	Detailer        ResourceDetailer
	WatchStarter    WatchStarterFunc
	DrillDown       *DrillDownConfig
	HasLogs         bool
	Dynamic         bool // true for CRD resources
}

ResourceDefinition contains all behavior for a resource type.

type ResourceDetail

type ResourceDetail struct {
	Name             string
	Namespace        string
	Kind             string
	UID              string
	CreatedAt        string
	Labels           map[string]string
	Annotations      map[string]string
	Fields           []DetailField
	Containers       []ContainerInfo
	YAML             string
	PodRelatives     *PodRelativesData
	ServiceRelatives *ServiceRelativesData
	Relatives        []RelativeSection

	// ReleaseHistory carries the `helm history` rows for a Helm Release.
	// Populated by enrichReleaseHistory (Phase 2c). Nil for every other kind.
	ReleaseHistory []ReleaseRevision

	// Conditions carries the resource's .status.conditions for display on the
	// Conditions tab. Populated by ExtractConditions; nil for kinds without
	// conditions (ConfigMap, Secret, Service, ServiceAccount, ...). The
	// Conditions tab is hidden when this slice is empty.
	Conditions []ConditionItem
}

ResourceDetail holds structured detail for a resource.

YAML, if non-empty, is the canonical serialized form of the resource — the detail panel renders it instead of the structured Fields/Containers when available. Structured fields are still used for synthetic detail views (e.g. container drill-down) that have no native YAML.

PodRelatives / ServiceRelatives are legacy typed payloads for the two kinds with rich domain-specific structure. Every other kind populates the generic Relatives slice instead — the UI dispatcher reads from the right field.

func GetResourceDetail

func GetResourceDetail(rt ResourceType, item ResourceItem) ResourceDetail

GetResourceDetail extracts structured detail via the DefaultRegistry.

type ResourceDetailer

type ResourceDetailer func(item ResourceItem) ResourceDetail

ResourceDetailer extracts detail from a ResourceItem.

type ResourceFetcher

type ResourceFetcher func(ctx context.Context, clientset kubernetes.Interface, namespace string) ([]ResourceItem, error)

ResourceFetcher fetches resources of a given type.

type ResourceItem

type ResourceItem struct {
	Row       []string
	Name      string
	Namespace string
	UID       string
	Raw       interface{}
}

ResourceItem holds a single resource's table row and metadata.

func FetchResourceByRef added in v1.3.0

func FetchResourceByRef(ctx context.Context, cs kubernetes.Interface, ref RefTarget) (ResourceItem, error)

FetchResourceByRef fetches a single resource by its kind + name + namespace and returns a ResourceItem ready for YAML rendering. Used by the Relatives tab's drill-to-popup flow.

Returns the same ResourceItem shape the table would produce, with Raw set to the typed object so MarshalItemYAML can serialize it correctly. Unknown resource types return an error rather than guessing.

func FetchResources

func FetchResources(ctx context.Context, clientset kubernetes.Interface, rt ResourceType, namespace string) ([]ResourceItem, error)

FetchResources lists resources of the given type via the DefaultRegistry.

type ResourceType

type ResourceType string

ResourceType identifies a Kubernetes resource kind supported by km8.

const (
	ResourceNamespaces          ResourceType = "namespaces"
	ResourceNodes               ResourceType = "nodes"
	ResourcePods                ResourceType = "pods"
	ResourceDeployments         ResourceType = "deployments"
	ResourceDaemonSets          ResourceType = "daemonsets"
	ResourceStatefulSets        ResourceType = "statefulsets"
	ResourceJobs                ResourceType = "jobs"
	ResourceCronJobs            ResourceType = "cronjobs"
	ResourceServices            ResourceType = "services"
	ResourceIngresses           ResourceType = "ingresses"
	ResourceConfigMaps          ResourceType = "configmaps"
	ResourceSecrets             ResourceType = "secrets"
	ResourceEvents              ResourceType = "events"
	ResourceClusterRoles        ResourceType = "clusterroles"
	ResourceClusterRoleBindings ResourceType = "clusterrolebindings"
	ResourceRoles               ResourceType = "roles"
	ResourceRoleBindings        ResourceType = "rolebindings"
	ResourceServiceAccounts     ResourceType = "serviceaccounts"

	ResourcePersistentVolumes      ResourceType = "persistentvolumes"
	ResourcePersistentVolumeClaims ResourceType = "persistentvolumeclaims"
	ResourceStorageClasses         ResourceType = "storageclasses"

	ResourceHorizontalPodAutoscalers ResourceType = "horizontalpodautoscalers"
	ResourcePodDisruptionBudgets     ResourceType = "poddisruptionbudgets"

	ResourceNetworkPolicies ResourceType = "networkpolicies"
	ResourceEndpointSlices  ResourceType = "endpointslices"
	ResourceIngressClasses  ResourceType = "ingressclasses"

	// ResourceReleases is the km8 27th ResourceType — Helm releases. Treated as
	// a normal ResourceType so existing graph/drill machinery is reused, but the
	// fetcher goes through `helm` CLI rather than client-go. Registered at
	// runtime only when `helm` is found on PATH (see helm.go).
	ResourceReleases ResourceType = "releases"
)

func AllResourceTypes

func AllResourceTypes() []ResourceType

AllResourceTypes returns all supported resource types in display order.

func (ResourceType) KubectlName

func (r ResourceType) KubectlName() string

KubectlName returns the kubectl resource name (e.g. "pod", "deployment").

func (ResourceType) String

func (r ResourceType) String() string

String returns the human-readable name of the resource type.

func (ResourceType) SupportsDrillDown

func (r ResourceType) SupportsDrillDown() bool

SupportsDrillDown returns true if this resource type can drill down to children.

type ServiceRelativesData added in v1.4.0

type ServiceRelativesData struct {
	Pods []RefTarget
}

ServiceRelativesData is the navigable-refs payload for a Service detail. Pods is the workload selected by the Service's label selector — each one is a drillable RefTarget so the user can answer "which pods does this Service route to?" in one keystroke.

Populated by EnrichRelatives at fetch time (it issues a CoreV1().Pods().List against the selector); the synchronous detailService can't do this because it has no clientset.

type SortTier added in v1.7.0

type SortTier struct {
	Column    string
	Ascending bool
}

SortTier is one rung in a multi-column sort. Column is matched against the kind's registered Column.Title (same dispatch as single-column SortItems). Ascending toggles direction within the tier only — each tier is independent.

type VolumeRef added in v1.3.0

type VolumeRef struct {
	Name string // volume name in spec.volumes
	Kind string // "configMap" / "secret" / "persistentVolumeClaim" / "emptyDir" / "hostPath" / "projected" / "downwardAPI" / "other"
	Ref  *RefTarget
}

VolumeRef describes a Pod volume's source. Ref is non-nil when the source is another K8s resource the user can drill into (ConfigMap, Secret, PVC).

type WatchErrMsg

type WatchErrMsg struct {
	Err error
}

WatchErrMsg is sent when the watcher encounters an error.

type WatchMsg

type WatchMsg struct {
	Items []ResourceItem
}

WatchMsg is sent when the resource list has been updated.

type WatchStarterFunc

type WatchStarterFunc func(ctx context.Context, clientset kubernetes.Interface, namespace string) (watch.Interface, error)

WatchStarterFunc starts a watch for a resource type.

type Watcher

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

Watcher manages a Watch connection for a single resource type and maintains a local cache of items. It integrates with Bubble Tea through a channel-based message pattern.

func NewWatcher

func NewWatcher(clientset kubernetes.Interface) *Watcher

NewWatcher creates a new Watcher for the given clientset.

func (*Watcher) Channels added in v1.0.4

func (w *Watcher) Channels() (<-chan WatchMsg, <-chan WatchErrMsg)

Channels returns both channels atomically, preventing a TOCTOU race where Start() replaces one channel between two separate Updates()/Errors() calls.

func (*Watcher) Errors

func (w *Watcher) Errors() <-chan WatchErrMsg

Errors returns the channel for receiving watch errors.

func (*Watcher) GetItem

func (w *Watcher) GetItem(index int) *ResourceItem

GetItem returns a single item by index, or nil if out of range.

func (*Watcher) GetItems

func (w *Watcher) GetItems() []ResourceItem

GetItems returns the current cached items.

func (*Watcher) Start

func (w *Watcher) Start(rt ResourceType, namespace string)

Start cancels any existing watch and starts watching the given resource type. It performs an initial List, then starts a Watch for incremental updates. Updates are sent to the internal channel — use WaitForUpdate() to receive them.

func (*Watcher) Stop

func (w *Watcher) Stop()

Stop cancels the current watch.

func (*Watcher) Updates

func (w *Watcher) Updates() <-chan WatchMsg

Updates returns the channel for receiving watch updates.

Jump to

Keyboard shortcuts

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