Documentation
¶
Overview ¶
Package config loads and validates the g9s configuration file.
Index ¶
- Constants
- Variables
- func DefaultPath() string
- func IsPlaceholder(p Project) bool
- type Config
- func (c *Config) AllPlaceholders() bool
- func (c *Config) BigQueryJobWindow() time.Duration
- func (c *Config) ComposerLocations(p Project) []string
- func (c *Config) CredentialsFile(p Project) string
- func (c *Config) DataprocRegions(p Project) []string
- func (c *Config) HasDataprocRegions(p Project) bool
- func (c *Config) KMSLocations(p Project) []string
- func (c *Config) LimitBackendGroups() int
- func (c *Config) LimitBigQueryJobs() int
- func (c *Config) LimitBigQueryTables() int
- func (c *Config) LimitCloudBuilds() int
- func (c *Config) LimitClusterJobs() int
- func (c *Config) LimitDNSRecordSets() int
- func (c *Config) LimitDataflowJobs() int
- func (c *Config) LimitDataprocJobsPerRegion() int
- func (c *Config) LimitKMSKeyRings() int
- func (c *Config) LimitServiceAccountKeyLookups() int
- func (c *Config) Path() string
- func (c *Config) Project(name string) (Project, bool)
- func (c *Config) Regions(p Project) []string
- func (c *Config) StorageObjectsPageSize() int
- type Defaults
- type Duration
- type Limits
- type Project
Constants ¶
const ( DefaultBigQueryJobs = 500 DefaultDataflowJobs = 500 DefaultDataprocJobsPerRegion = 200 DefaultClusterJobs = 200 DefaultBigQueryTables = 1000 DefaultDNSRecordSets = 1000 DefaultBackendGroups = 40 DefaultServiceAccountKeyLookups = 200 DefaultKMSKeyRings = 100 DefaultCloudBuilds = 200 )
Default row caps. These are the numbers that used to be compiled into each lister, kept exactly as they were so upgrading changes nothing on its own.
Variables ¶
var PlaceholderProjectIDs = []string{"my-sandbox-project", "my-prod-data-project"}
PlaceholderProjectIDs are the project IDs `g9s -init` writes.
They exist here rather than only in the template so the two cannot drift: the UI needs to recognise an unedited config, and recognising it by a string copied into another file is how that check quietly stops working.
Functions ¶
func DefaultPath ¶
func DefaultPath() string
DefaultPath resolves the config location: $G9S_CONFIG, then $XDG_CONFIG_HOME/g9s/config.yaml, then ~/.config/g9s/config.yaml.
func IsPlaceholder ¶ added in v0.1.25
IsPlaceholder reports whether a project is one `g9s -init` wrote and nobody has edited yet.
Worth detecting because an unedited config looks exactly like a working one until the first login, which then fails against a project that does not exist — and the error comes back from Google talking about permissions, which sends people looking in entirely the wrong place.
Types ¶
type Config ¶
type Config struct {
Defaults Defaults `yaml:"defaults"`
Projects []Project `yaml:"projects"`
// contains filtered or unexported fields
}
Config is the top-level configuration document.
func (*Config) AllPlaceholders ¶ added in v0.1.25
AllPlaceholders reports whether every configured project is still a placeholder, which means the config has not been edited at all.
func (*Config) BigQueryJobWindow ¶ added in v0.1.3
BigQueryJobWindow is how far back to list BigQuery jobs.
func (*Config) ComposerLocations ¶
ComposerLocations returns the locations to sweep for Composer environments.
func (*Config) CredentialsFile ¶ added in v0.1.5
CredentialsFile returns the existing credentials file to read for a project, or "" when g9s manages the credentials itself.
func (*Config) DataprocRegions ¶
dataprocRegions returns the regions to sweep for Dataproc clusters, most specific setting first. "global" is always included because clusters can be created there and it is easy to forget.
func (*Config) HasDataprocRegions ¶
HasDataprocRegions reports whether any region setting applies to Dataproc for this project. When false, DataprocRegions falls back to just "global", and the lister says so rather than letting the narrow sweep look complete.
func (*Config) KMSLocations ¶ added in v0.1.16
KMSLocations returns the locations to sweep for KMS key rings.
Regions plus "global", always, and for a stronger reason than Dataproc's: a key ring in the global location is not an edge case, it is where most projects put their first one. Sweeping only the configured regions would show an empty KMS table to a project whose keys all exist.
func (*Config) LimitBackendGroups ¶ added in v0.1.17
func (*Config) LimitBigQueryJobs ¶ added in v0.1.17
func (*Config) LimitBigQueryTables ¶ added in v0.1.17
func (*Config) LimitCloudBuilds ¶ added in v0.1.29
func (*Config) LimitClusterJobs ¶ added in v0.1.17
func (*Config) LimitDNSRecordSets ¶ added in v0.1.17
func (*Config) LimitDataflowJobs ¶ added in v0.1.17
func (*Config) LimitDataprocJobsPerRegion ¶ added in v0.1.17
func (*Config) LimitKMSKeyRings ¶ added in v0.1.17
func (*Config) LimitServiceAccountKeyLookups ¶ added in v0.1.17
func (*Config) Path ¶ added in v0.1.25
Path is the file this config was loaded from, empty if it was not loaded from one.
func (*Config) Regions ¶ added in v0.1.6
Regions returns the regions to sweep for a kind with no override of its own, most specific setting first. Cloud Run uses this: its API refuses the "-" wildcard, so the sweep is only ever as wide as this list.
func (*Config) StorageObjectsPageSize ¶ added in v0.1.20
StorageObjectsPageSize returns the human-sized page used by the object browser. A nil or hand-built Config gets the same default as one loaded from YAML; tests and embedded callers do not necessarily pass through applyDefaults.
type Defaults ¶
type Defaults struct {
// Regions is the fallback region list for every region-scoped resource.
Regions []string `yaml:"regions"`
// DataprocRegions narrows the Dataproc fan-out for all projects.
DataprocRegions []string `yaml:"dataproc_regions"`
// ComposerLocations narrows the Composer fan-out for all projects.
ComposerLocations []string `yaml:"composer_locations"`
// CredentialDir is where per-project gcloud config directories live.
CredentialDir string `yaml:"credential_dir"`
// GcloudPath is the gcloud binary to shell out to for login.
GcloudPath string `yaml:"gcloud_path"`
// CredentialsFile points every project at an existing credentials file
// instead of a per-project directory g9s logs into. See Project.
CredentialsFile string `yaml:"credentials_file"`
// LoginNoBrowser makes `l` always use gcloud's --no-browser flow, the same
// as pressing `L` every time.
//
// Worth setting on a machine behind a proxy. gcloud's ordinary login ends
// with the browser fetching http://localhost:<port>/ to hand the
// authorization code back, and a browser that sends localhost through a
// proxy never delivers it — the sign-in succeeds and the terminal waits
// forever. Whether the browser does that is a property of this machine, not
// of any one project, which is why this lives in defaults.
LoginNoBrowser bool `yaml:"login_no_browser"`
// ListTimeout bounds a single refresh across all regions.
ListTimeout Duration `yaml:"list_timeout"`
// BigQueryJobWindow is how far back the BigQuery jobs table looks. Jobs are
// kept for six months, which is far more than a "what is running now"
// table can show, so the window is what makes the listing a complete
// answer rather than a truncated one.
BigQueryJobWindow Duration `yaml:"bigquery_job_window"`
// StorageObjectsPageSize is the number of object and folder rows shown in
// one UI page while browsing a bucket. It is not a total cap: the UI retains
// the continuation token and can load the next page.
StorageObjectsPageSize int `yaml:"storage_objects_page_size"`
// ClipboardLimit is the largest OSC 52 escape sequence, in bytes, that this
// terminal is believed to accept.
//
// It exists because the failure it prevents is silent. `y` writes the
// clipboard as one escape sequence, and a terminal that considers it too
// long drops the whole thing without reporting anything — so g9s would say
// "copied" over a clipboard that never changed. A stock xterm cuts off
// around 8 KB and tmux refuses entirely unless set-clipboard is on, while
// modern terminals take far more, and nothing in the protocol lets g9s ask
// which it is talking to. So the default is the conservative one and the
// number is yours to raise once you know your terminal.
//
// Zero uses the default. Negative removes the check, which means trusting
// the terminal to say something when it truncates — most do not.
ClipboardLimit int `yaml:"clipboard_limit"`
// Limits raises or removes the per-kind row caps.
Limits Limits `yaml:"limits"`
}
Defaults supply values for any project that does not override them.
type Limits ¶ added in v0.1.17
type Limits struct {
// BigQueryJobs caps the BigQuery jobs table. The window bounds it first;
// this is the backstop for a busy hour inside that window.
BigQueryJobs int `yaml:"bigquery_jobs"`
// DataflowJobs caps the Dataflow jobs table.
DataflowJobs int `yaml:"dataflow_jobs"`
// DataprocJobsPerRegion caps each region's Dataproc job listing. It is per
// region, so the table can hold this many times your region count.
DataprocJobsPerRegion int `yaml:"dataproc_jobs_per_region"`
// ClusterJobs caps the per-cluster Dataproc job drill-down.
ClusterJobs int `yaml:"cluster_jobs"`
// BigQueryTables caps one dataset's table listing.
BigQueryTables int `yaml:"bigquery_tables"`
// DNSRecordSets caps one zone's record listing.
DNSRecordSets int `yaml:"dns_record_sets"`
// BackendGroups caps the getHealth calls one backend-health drill-down
// makes. Unlike the others this bounds *requests*, not rows: each group is
// its own round trip, so raising it costs latency rather than memory.
BackendGroups int `yaml:"backend_groups"`
// ServiceAccountKeyLookups caps how many accounts get their key ages read.
// Also a request bound: one keys.list per account.
ServiceAccountKeyLookups int `yaml:"service_account_key_lookups"`
// KMSKeyRings caps how many key rings per location get their keys read.
// One cryptoKeys.list per ring, so this is a request bound too.
KMSKeyRings int `yaml:"kms_key_rings"`
// CloudBuilds caps the build history table. Build records are kept
// indefinitely, so without a bound this is the one listing that grows
// without limit for the life of the project.
CloudBuilds int `yaml:"cloud_builds"`
}
Limits are the row caps each listing stops at.
Every one of these was a constant compiled into a lister, which made the bound the tool's opinion rather than the reader's. The defaults are unchanged and are sized for a table a person scrolls; the point of the block is that a project big enough to hit one is no longer stuck at a number it did not pick.
Zero means "use the default". A negative value means no cap at all, which is a real choice with real consequences — a zone with 90,000 record sets will fetch all 90,000 — so it has to be asked for explicitly rather than being what an empty field happens to mean.
type Project ¶
type Project struct {
// Name is the label shown in the picker. Also names the credential dir.
Name string `yaml:"name"`
// ProjectID is the real GCP project ID.
ProjectID string `yaml:"project_id"`
// Account is the support account email passed to `gcloud --account`.
// Empty means "whatever gcloud picks", which is fine for a personal login.
Account string `yaml:"account"`
// Description is free text shown alongside the project in the picker.
Description string `yaml:"description"`
// CredentialsFile is an existing credentials file to read for this
// project, instead of the per-project directory g9s logs into.
//
// This is the way in when the login handshake cannot complete at all —
// behind a proxy that swallows the loopback redirect, gcloud's browser
// flow and its --no-browser flow both end at a localhost the browser
// cannot reach. Point this at credentials obtained any way that does
// work, most often the ordinary ~/.config/gcloud ADC, and g9s reads them
// rather than demanding a login it cannot finish.
//
// g9s only ever reads this file. Keeping it fresh is then yours, which is
// the trade: no isolation between projects that share one file, and no
// login for g9s to run.
CredentialsFile string `yaml:"credentials_file"`
// Production marks a project where a mistake is expensive.
//
// It only ever adds friction: a project marked production makes every
// action confirmation louder and demands the resource's name be typed,
// including for actions that are not otherwise destructive. It cannot
// make anything easier, which is what makes it safe to guess at — see
// IsProduction.
//
// A pointer so that "unset" and "explicitly false" are different answers.
// Someone who writes `production: false` on a project called prod-data has
// said something deliberate, and guessing over the top of it would make
// the setting a lie.
Production *bool `yaml:"production"`
Regions []string `yaml:"regions"`
DataprocRegions []string `yaml:"dataproc_regions"`
ComposerLocations []string `yaml:"composer_locations"`
}
Project is one GCP project as the user works with it: the project ID plus the identity used to reach it and the regions worth scanning.
func (Project) IsProduction ¶ added in v0.1.30
IsProduction reports whether a project should be treated as production.
An explicit setting always wins. Otherwise the name and project ID are checked for the usual markers, because the common case is that nobody set the flag and the project is called something like acme-dataeng-prod-4471 — and the first time anyone thinks about this setting should not be after stopping the wrong instance.