Documentation
¶
Overview ¶
Package columns is the single source of truth for the columns rendered by `toolkit get` (CLI table/csv/tsv) and the TUI table view. One Set or GroupedSet is defined per domain.Category; both surfaces consume them through adapters.
Index ¶
- Variables
- func HelpTable(cat domain.Category) (headers []string, rows [][]string)
- func IsRegistered(cat domain.Category) bool
- func KeysFor(cat domain.Category) []string
- func RatioSumFor(cat domain.Category) float64
- func RenderTable(cat domain.Category, items any, selected []string) ([]string, [][]string, error)
- func RenderTableForExport(cat domain.Category, items any, realm, region string, selected []string) ([]string, [][]string, error)
- func TitlesFor(cat domain.Category) []string
- type Column
- type GroupedColumn
- type GroupedSet
- type Set
- type UnknownKeyError
Constants ¶
This section is empty.
Variables ¶
var ( ConsolePropertyDefinitionColumns = DefinitionColumns[models.ConsolePropertyDefinition]() PropertyDefinitionColumns = DefinitionColumns[models.PropertyDefinition]() )
Pre-instantiated typed sets — the registry uses these directly so each call doesn't reconstruct the closures.
var ( ConsolePropertyRegionalOverrideColumns = RegionalOverrideColumns[models.ConsolePropertyRegionalOverride]() PropertyRegionalOverrideColumns = RegionalOverrideColumns[models.PropertyRegionalOverride]() )
Canonical column sets for the regional-override categories, instantiated from the shared RegionalOverrideColumns generic.
var ( ConsolePropertyTenancyOverrideColumns = TenancyOverrideColumns[models.ConsolePropertyTenancyOverride]() PropertyTenancyOverrideColumns = TenancyOverrideColumns[models.PropertyTenancyOverride]() )
Canonical column sets for the tenancy-override categories, instantiated from the shared TenancyOverrideColumns generic.
var AliasColumns = Set[domain.Category]{Columns: []Column[domain.Category]{ { Title: "Name", Key: "name", Ratio: 0.40, Render: func(c domain.Category) string { return c.String() }, }, { Title: "Aliases", Key: "aliases", Ratio: 0.60, Render: func(c domain.Category) string { return strings.Join(c.Aliases(), ", ") }, }, }}
AliasColumns is the canonical column set for domain.Alias. Canonical follows the TUI's 1-row-per-category shape (intentional behaviour change from the CLI's 1-row-per-alias layout).
var BaseModelColumns = Set[models.BaseModel]{Columns: []Column[models.BaseModel]{ { Title: "Name", Key: "name", Ratio: 0.22, Render: func(m models.BaseModel) string { return m.Name }, }, { Title: "Display Name", Key: "display-name", Ratio: 0.26, Render: func(m models.BaseModel) string { return m.DisplayName }, }, { Title: "Version", Key: "version", Ratio: 0.08, Render: func(m models.BaseModel) string { return m.Version }, }, { Title: "DAC Shape", Key: "dac-shape", Ratio: 0.14, Render: baseModelDACShape, }, { Title: "Size", Key: "size", Ratio: 0.07, Render: func(m models.BaseModel) string { return m.ParameterSize }, }, { Title: "Context", Key: "context", Ratio: 0.07, Render: func(m models.BaseModel) string { return strconv.Itoa(m.MaxTokens) }, }, { Title: "Flags", Key: "flags", Ratio: 0.09, Render: func(m models.BaseModel) string { return m.Flags() }, }, { Title: "Status", Key: "status", Ratio: 0.07, Render: func(m models.BaseModel) string { return m.Status }, }, }}
BaseModelColumns is the canonical column set for domain.BaseModel. 8 columns, ratios sum to 1.00. Internal/Vendor/Type were dropped in favor of Display Name + DAC Shape + Size + Context, which carry more operator-useful information; consumers that still need the dropped fields can read them from the JSON struct (`-o json`).
var DACColumns = GroupedSet[models.DedicatedAICluster]{Columns: []GroupedColumn[models.DedicatedAICluster]{ { Title: "Name", Key: "name", Ratio: 0.20, TruncateMiddle: true, Render: func(_ string, d models.DedicatedAICluster) string { return d.Name }, RenderForExport: func(realm, region string, _ string, d models.DedicatedAICluster) string { return d.OCID(realm, region) }, }, { Title: "Tenant", Key: "tenant", Ratio: 0.17, TruncateMiddle: true, Render: func(k string, _ models.DedicatedAICluster) string { return k }, RenderForExport: func(realm, _ string, _ string, d models.DedicatedAICluster) string { return d.TenancyOCID(realm) }, }, { Title: "Internal", Key: "internal", Ratio: 0.09, Render: func(_ string, d models.DedicatedAICluster) string { return d.OwnerState() }, }, { Title: "Usage", Key: "usage", Ratio: 0.07, Render: func(_ string, d models.DedicatedAICluster) string { return d.Usage() }, }, { Title: "Type", Key: "type", Ratio: 0.07, Render: func(_ string, d models.DedicatedAICluster) string { return d.Type }, }, { Title: "Model", Key: "model", Ratio: 0.10, Render: func(_ string, d models.DedicatedAICluster) string { return d.ModelName }, }, { Title: "Shape/Profile", Key: "shape-profile", Ratio: 0.12, Render: func(_ string, d models.DedicatedAICluster) string { return dacShapeOrProfile(d) }, }, { Title: "Size", Key: "size", Ratio: 0.06, Render: func(_ string, d models.DedicatedAICluster) string { return strconv.Itoa(d.Size) }, }, { Title: "Age", Key: "age", Ratio: 0.06, Render: func(_ string, d models.DedicatedAICluster) string { return d.Age }, }, { Title: "Status", Key: "status", Ratio: 0.06, Render: func(_ string, d models.DedicatedAICluster) string { return d.Status }, }, }}
DACColumns is the canonical column set for domain.DedicatedAICluster.
Ordering is name-first, tenant-key-second (matches TUI; Decision #4). The Name and Tenant columns carry an RenderForExport closure that produces fully-qualified OCIDs (vs the suffix-only display form); substitution happens per-column inside the column registry, so reordering the columns here doesn't require companion edits in the CSV export path.
Name was rebalanced from 0.35 to 0.20 to match ImportedModel and free width for the narrow sortable columns (Internal/Usage/Size/Age); they previously had no headroom for the ↕ sortable indicator (or even the full title in Internal's case). The freed 0.15 is redistributed to the columns that needed breathing room, including Status — its 6-char title and ACTIVE/FAILED/READY values would truncate at ratio 0.04.
var EnvironmentColumns = Set[models.Environment]{Columns: []Column[models.Environment]{ { Title: "Name", Key: "name", Ratio: 0.20, Render: func(e models.Environment) string { return e.GetName() }, }, { Title: "Realm", Key: "realm", Ratio: 0.15, Render: func(e models.Environment) string { return e.Realm }, }, { Title: "Type", Key: "type", Ratio: 0.15, Render: func(e models.Environment) string { return e.Type }, }, { Title: "Region", Key: "region", Ratio: 0.50, Render: func(e models.Environment) string { return e.Region }, }, }}
EnvironmentColumns is the canonical column set for domain.Environment. Matches today's TUI column order.
var GPUNodeColumns = GroupedSet[models.GPUNode]{Columns: []GroupedColumn[models.GPUNode]{ { Title: "Name", Key: "name", Ratio: 0.15, Render: func(_ string, n models.GPUNode) string { return n.Name }, }, { Title: "Pool", Key: "pool", Ratio: 0.22, Render: func(k string, _ models.GPUNode) string { return k }, }, { Title: "Type", Key: "type", Ratio: 0.15, Render: func(_ string, n models.GPUNode) string { return n.InstanceType }, }, { Title: "Total", Key: "total", Ratio: 0.06, Render: func(_ string, n models.GPUNode) string { return strconv.Itoa(n.Allocatable) }, }, { Title: "Free", Key: "free", Ratio: 0.06, Render: func(_ string, n models.GPUNode) string { return strconv.Itoa(n.Allocatable - n.Allocated) }, }, { Title: "Healthy", Key: "healthy", Ratio: 0.06, Render: func(_ string, n models.GPUNode) string { return strconv.FormatBool(n.IsHealthy()) }, }, { Title: "Ready", Key: "ready", Ratio: 0.06, Render: func(_ string, n models.GPUNode) string { return strconv.FormatBool(n.IsReady) }, }, { Title: "Age", Key: "age", Ratio: 0.06, Render: func(_ string, n models.GPUNode) string { return n.Age }, }, { Title: "Status", Key: "status", Ratio: 0.18, Render: func(_ string, n models.GPUNode) string { return n.GetStatus() }, }, }}
GPUNodeColumns is the canonical column set for domain.GPUNode. Ordering is name-first, pool-key-second (matches TUI; Decision #4).
var GPUPoolColumns = Set[models.GPUPool]{Columns: []Column[models.GPUPool]{ { Title: "Name", Key: "name", Ratio: 0.22, Render: func(p models.GPUPool) string { return p.Name }, }, { Title: "Shape", Key: "shape", Ratio: 0.20, Render: func(p models.GPUPool) string { return p.Shape }, }, { Title: "AD", Key: "ad", Ratio: 0.06, Render: func(p models.GPUPool) string { return p.AvailabilityDomain }, }, { Title: "Size", Key: "size", Ratio: 0.06, Render: func(p models.GPUPool) string { return strconv.Itoa(p.Size) }, }, { Title: "Actual Size", Key: "actual-size", Ratio: 0.10, Render: func(p models.GPUPool) string { return strconv.Itoa(p.ActualSize) }, }, { Title: "GPUs", Key: "gpus", Ratio: 0.06, Render: func(p models.GPUPool) string { return strconv.Itoa(p.GPUs()) }, }, { Title: "OKE Managed", Key: "oke-managed", Ratio: 0.10, Render: func(p models.GPUPool) string { return strconv.FormatBool(p.IsOkeManaged) }, }, { Title: "Capacity Type", Key: "capacity-type", Ratio: 0.10, Render: func(p models.GPUPool) string { return p.CapacityType }, }, { Title: "Status", Key: "status", Ratio: 0.10, Render: func(p models.GPUPool) string { return p.Status }, }, }}
GPUPoolColumns is the canonical column set for domain.GPUPool. Matches today's CLI and TUI tables.
var ImportedModelColumns = GroupedSet[models.ImportedModel]{Columns: []GroupedColumn[models.ImportedModel]{ { Title: "Name", Key: "name", Ratio: 0.20, TruncateMiddle: true, Render: func(_ string, m models.ImportedModel) string { return m.Name }, RenderForExport: func(realm, region string, _ string, m models.ImportedModel) string { return m.OCID(realm, region) }, }, { Title: "Tenant", Key: "tenant", Ratio: 0.22, TruncateMiddle: true, Render: func(k string, _ models.ImportedModel) string { return k }, RenderForExport: func(realm, _ string, _ string, m models.ImportedModel) string { return m.TenancyOCID(realm) }, }, { Title: "Namespace", Key: "namespace", Ratio: 0.15, TruncateMiddle: true, Render: func(_ string, m models.ImportedModel) string { return m.Namespace }, }, { Title: "Display Name", Key: "display-name", Ratio: 0.27, Render: func(_ string, m models.ImportedModel) string { return m.DisplayName }, }, { Title: "Vendor", Key: "vendor", Ratio: 0.10, Render: func(_ string, m models.ImportedModel) string { return m.Vendor }, }, { Title: "Status", Key: "status", Ratio: 0.06, Render: func(_ string, m models.ImportedModel) string { return m.Status }, }, }}
ImportedModelColumns is the canonical column set for domain.ImportedModel. 6 columns, ratios sum to 1.00. Version was dropped (imported models are keyed by Name, which already carries the operator-meaningful versioning convention); its 0.05 width was released to Vendor so vendor strings have room to render without truncation. Version stays reachable via `-o json`. Ordering is name-first, tenant-key-second (matches TUI; Decision #4).
var LimitDefinitionColumns = Set[models.LimitDefinition]{Columns: []Column[models.LimitDefinition]{ { Title: "Name", Key: "name", Ratio: 0.32, Render: func(d models.LimitDefinition) string { return d.Name }, }, { Title: "Description", Key: "description", Ratio: 0.48, Render: func(d models.LimitDefinition) string { return d.Description }, }, { Title: "Scope", Key: "scope", Ratio: 0.08, Render: func(d models.LimitDefinition) string { return d.Scope }, }, { Title: "Min", Key: "min", Ratio: 0.06, Render: func(d models.LimitDefinition) string { return d.DefaultMin }, }, { Title: "Max", Key: "max", Ratio: 0.06, Render: func(d models.LimitDefinition) string { return d.DefaultMax }, }, }}
LimitDefinitionColumns is the canonical column set for domain.LimitDefinition. Matches today's CLI and TUI tables.
var LimitRegionalOverrideColumns = Set[models.LimitRegionalOverride]{Columns: []Column[models.LimitRegionalOverride]{ { Title: "Name", Key: "name", Ratio: 0.40, Render: func(o models.LimitRegionalOverride) string { return o.Name }, }, { Title: "Regions", Key: "regions", Ratio: 0.30, Render: func(o models.LimitRegionalOverride) string { return strings.Join(o.Regions, ", ") }, }, { Title: "Min", Key: "min", Ratio: 0.15, Render: func(o models.LimitRegionalOverride) string { return limitOverrideMin(o.Values) }, }, { Title: "Max", Key: "max", Ratio: 0.15, Render: func(o models.LimitRegionalOverride) string { return limitOverrideMax(o.Values) }, }, }}
LimitRegionalOverrideColumns is the canonical column set for domain.LimitRegionalOverride: Name, Regions, Min, Max (CLI matches TUI).
var LimitTenancyOverrideColumns = GroupedSet[models.LimitTenancyOverride]{Columns: []GroupedColumn[models.LimitTenancyOverride]{ { Title: "Name", Key: "name", Ratio: 0.40, Render: func(_ string, v models.LimitTenancyOverride) string { return v.Name }, }, { Title: "Tenant", Key: "tenant", Ratio: 0.24, TruncateMiddle: true, Render: func(k string, _ models.LimitTenancyOverride) string { return k }, }, { Title: "Regions", Key: "regions", Ratio: 0.20, Render: func(_ string, v models.LimitTenancyOverride) string { return strings.Join(v.Regions, ", ") }, }, { Title: "Min", Key: "min", Ratio: 0.08, Render: func(_ string, v models.LimitTenancyOverride) string { return limitOverrideMin(v.Values) }, }, { Title: "Max", Key: "max", Ratio: 0.08, Render: func(_ string, v models.LimitTenancyOverride) string { return limitOverrideMax(v.Values) }, }, }}
LimitTenancyOverrideColumns is the canonical column set for domain.LimitTenancyOverride: Name, Tenant, Regions, Min, Max (CLI matches TUI per spec Decision #9).
var ModelArtifactColumns = GroupedSet[models.ModelArtifact]{Columns: []GroupedColumn[models.ModelArtifact]{ { Title: "Name", Key: "name", Ratio: 0.50, Render: func(_ string, a models.ModelArtifact) string { return a.Name }, }, { Title: "Model Internal Name", Key: "model-internal-name", Ratio: 0.30, Render: func(_ string, a models.ModelArtifact) string { return a.ModelName }, }, { Title: "GPU Config", Key: "gpu-config", Ratio: 0.10, Render: func(_ string, a models.ModelArtifact) string { return a.GPUConfig() }, }, { Title: "TensorRT", Key: "tensorrt", Ratio: 0.10, Render: func(_ string, a models.ModelArtifact) string { return a.TensorRTVersion }, }, }}
ModelArtifactColumns is the canonical column set for domain.ModelArtifact. The group key is the parent BaseModel name (equals a.ModelName). The "Model Internal Name" column renders a.ModelName (ignores k) to match TUI behaviour. Ordering is name-first, key-second (Decision #4).
var ServiceTenancyColumns = Set[models.ServiceTenancy]{Columns: []Column[models.ServiceTenancy]{ { Title: "Name", Key: "name", Ratio: 0.15, Render: func(s models.ServiceTenancy) string { return s.Name }, }, { Title: "Realm", Key: "realm", Ratio: 0.10, Render: func(s models.ServiceTenancy) string { return s.Realm }, }, { Title: "Type", Key: "environment", Ratio: 0.10, Render: func(s models.ServiceTenancy) string { return s.Environment }, }, { Title: "Home Region", Key: "home-region", Ratio: 0.15, Render: func(s models.ServiceTenancy) string { return s.HomeRegion }, }, { Title: "Regions", Key: "regions", Ratio: 0.50, Render: func(s models.ServiceTenancy) string { return strings.Join(s.Regions, ", ") }, }, }}
ServiceTenancyColumns is the canonical column set for domain.ServiceTenancy. The Environment field is displayed as "Type" — the title kept from the pre-canonical TUI because the SortType binding (registry.go) and operator mental model both expect "Type". The struct field stays Environment.
var TenantColumns = Set[models.Tenant]{Columns: []Column[models.Tenant]{ { Title: "Name", Key: "name", Ratio: 0.20, Render: func(t models.Tenant) string { return t.Name }, }, { Title: "OCIDs", Key: "ocid", Ratio: 0.60, Render: func(t models.Tenant) string { return strings.Join(t.IDs, ",") }, }, { Title: "Internal", Key: "internal", Ratio: 0.10, Render: func(t models.Tenant) string { return fmt.Sprint(t.IsInternal) }, }, { Title: "Note", Key: "note", Ratio: 0.10, Render: func(t models.Tenant) string { return t.Note }, }, }}
TenantColumns is the canonical column set for domain.Tenant. The second column's Title is "OCIDs" (plural) — one tenant can have multiple OCIDs (Tenant.IDs is a slice, and Tenant.IsFaulty flags >1 IDs). The cell joins them with commas. Key stays "ocid" for CLI --columns stability with prior releases.
Functions ¶
func HelpTable ¶
HelpTable returns a (Key, Title) row per column of cat, for the `--columns help` output. Empty if cat is unregistered.
func IsRegistered ¶
IsRegistered reports whether cat has a canonical column set.
func KeysFor ¶
KeysFor returns the declared keys for cat in order. Returns nil for unregistered categories.
func RatioSumFor ¶
RatioSumFor returns the sum of Ratio across all columns of cat (for the ratios-sum-to-1 registry test).
func RenderTable ¶
RenderTable is the single entrypoint the CLI calls. It dispatches on cat via the registry, applies --columns selection, and produces headers+rows for the chosen encoding (table/csv/tsv). headers are uppercased to preserve today's CLI table headers (NAME, STATUS, ...); the TUI adapter (in internal/ui/tui) uses Titles as-is.
`items` must be the concrete payload for cat. `selected` is the parsed --columns list (empty means "render every column").
func RenderTableForExport ¶
func RenderTableForExport(cat domain.Category, items any, realm, region string, selected []string) ([]string, [][]string, error)
RenderTableForExport mirrors RenderTable but consults each column's RenderForExport when present, producing the values downstream OCI tooling expects (e.g. fully-qualified OCIDs in place of raw Name suffixes for DAC and ImportedModel rows). Columns without RenderForExport fall back to Render, so categories that have nothing export-specific to say behave identically to RenderTable.
When either realm or region is empty the function short-circuits to RenderTable — RenderForExport closures typically format both into the output, and a partial env would produce malformed OCIDs like `ocid1.<type>.oc1..suffix` (missing region) or `ocid1.<type>..iad.suffix` (missing realm). Callers without a fully-populated env (e.g. unit tests that exercise the column registry directly) get raw display-mode output.
Types ¶
type Column ¶
type Column[T any] struct { Title string Key string Ratio float64 Render func(T) string RenderForExport func(realm, region string, item T) string TruncateMiddle bool }
Column is a column for a flat (non-grouped) category.
TruncateMiddle is an optional rendering hint: when the cell value is wider than the column at display time, the TUI elides the MIDDLE (head + "…" + tail) rather than chopping the tail. Useful for OCID-suffix-shaped values where the head identifies the resource shape and the tail is the distinguishing portion. CLI surfaces ignore this hint — they emit the full value.
RenderForExport is an optional alternate renderer used by file/CSV export paths (TUI <e> and CLI `-o csv`/`-o tsv` when env is set). Use it when the export-appropriate value is fundamentally different from the display value — e.g., expanding an OCID-suffix Name into the fully-qualified ocid1.<type>.<realm>.<region>.<suffix> form that downstream OCI tooling expects. Nil means "use Render".
The signature carries both `realm` and `region` even though most flat categories won't reference either — keeps the export-mode contract symmetric with GroupedColumn.RenderForExport and leaves room for future flat columns whose export form depends on env (e.g. a tenancy OCID column on the Tenant view).
type GroupedColumn ¶
type GroupedColumn[T any] struct { Title string Key string Ratio float64 Render func(key string, item T) string RenderForExport func(realm, region, key string, item T) string TruncateMiddle bool }
GroupedColumn is a column for a grouped category (loader returns map[string][]T). Render receives both the group key and the item; any column can use either. A "group key column" is just a GroupedColumn whose Render ignores `item` and returns `key`.
TruncateMiddle and RenderForExport have the same semantics as Column.TruncateMiddle / Column.RenderForExport; RenderForExport's signature carries the group key alongside realm/region so a column can substitute its display value with an export-mode representation that depends on either.
type GroupedSet ¶
type GroupedSet[T any] struct { Columns []GroupedColumn[T] }
GroupedSet is the canonical column list for a grouped category.
func TenancyOverrideColumns ¶
func TenancyOverrideColumns[T models.DefinitionOverride]() GroupedSet[T]
TenancyOverrideColumns is parameterized by the concrete DefinitionOverride type (ConsolePropertyTenancyOverride or PropertyTenancyOverride); both satisfy models.DefinitionOverride.
Columns: Name, Tenant, Regions, Value (CLI matches TUI per spec Decision #9).
func (GroupedSet[T]) Keys ¶
func (g GroupedSet[T]) Keys() []string
Keys returns the keys declared on g in order.
func (GroupedSet[T]) RatioSum ¶
func (g GroupedSet[T]) RatioSum() float64
RatioSum returns the sum of column Ratio values on g.
func (GroupedSet[T]) Select ¶
func (g GroupedSet[T]) Select(keys []string) ([]GroupedColumn[T], error)
Select / Keys / Titles / RatioSum mirrors for GroupedSet.
func (GroupedSet[T]) Titles ¶
func (g GroupedSet[T]) Titles() []string
Titles returns the column titles declared on g in order.
type Set ¶
Set is the canonical column list for a flat category.
func DefinitionColumns ¶
func DefinitionColumns[T models.Definition]() Set[T]
DefinitionColumns is parameterized by the concrete Definition type (ConsolePropertyDefinition or PropertyDefinition); both satisfy models.Definition.
func RegionalOverrideColumns ¶
func RegionalOverrideColumns[T models.DefinitionOverride]() Set[T]
RegionalOverrideColumns is parameterized by the concrete DefinitionOverride type (ConsolePropertyRegionalOverride or PropertyRegionalOverride); both satisfy models.DefinitionOverride.
type UnknownKeyError ¶
UnknownKeyError is returned by Set.Select / GroupedSet.Select when one or more requested keys are not present in the set.
func (*UnknownKeyError) Error ¶
func (e *UnknownKeyError) Error() string