Help us shape the future of Go! Take the 2026 Go Developer Survey

config

package
v0.4.3 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package config resolves one run's settings from the flags, the environment and an optional JSON file, in that order of precedence.

Index

Constants

View Source
const (
	FlagConfig      = "config"
	FlagLogLevel    = "log-level"
	FlagDryRun      = "dry-run"
	FlagController  = "controller"
	FlagAccessToken = "access-token"
	FlagInsecure    = "insecure"
	FlagFormat      = "format"
	FlagPretty      = "pretty"
	FlagTimeout     = "timeout"
	FlagSortBy      = "sort-by"
	FlagListKeys    = "list-keys"
	FlagSortOrder   = "sort-order"
	FlagColumns     = "columns"
	FlagRadio       = "radio"
	FlagSSID        = "ssid"
	FlagAPName      = "ap-name"
	FlagUsername    = "username"
	FlagPassword    = "password"
	FlagYes         = "yes"
	FlagSlot        = "slot"

	// FlagMAC names a client by address. It is its own flag rather than FlagAPName reused: a
	// client carries no name on the wire, so a row and the wire share the address.
	FlagMAC = "mac"

	// FlagName is the tag a set or delete leaf writes. The access-point target reuses
	// FlagAPName rather than this: show client already spells that one, so the target and
	// the filter cannot drift apart.
	FlagName = "name"

	FlagDescription   = "description"
	FlagProfile24GHz  = "profile-24ghz"
	FlagProfile5GHz   = "profile-5ghz"
	FlagProfile6GHz   = "profile-6ghz"
	FlagAPJoinProfile = "ap-join-profile"
	FlagFlexProfile   = "flex-profile"
	FlagLocalSite     = "local-site"
	FlagWLAN          = "wlan"
	FlagPolicyProfile = "policy-profile"
)

Flag names, shared by the definitions in internal/cli and the lookups here so the two cannot drift.

View Source
const (
	KindPolicyTag = "policy tag"
	KindSiteTag   = "site tag"
	KindRFTag     = "RF tag"
)

The tag kinds, spelled as the noun every message about them uses rather than as the set and delete leaf names, which are hyphenated. A controller keys each kind in its own list, so a name is only unique within one kind.

View Source
const (
	FormatTable = "table"
	FormatJSON  = "json"
)
View Source
const (
	OrderAsc  = "asc"
	OrderDesc = "desc"
)
View Source
const (
	DefaultFormat    = FormatTable
	DefaultSortOrder = OrderAsc
)

Flag defaults, declared once so the flag definition in internal/cli and the merge below cannot disagree about what an unset value means.

View Source
const (
	Band24 = "2.4"
	Band5  = "5"
	Band6  = "6"
)

Radio band selectors accepted by --radio. They are the display values of the band column, so a filter and a rendered row read the same.

View Source
const (
	// EnvController supplies --controller. The sibling exporter reads the same name
	// for its single host, so one pair of variables drives both tools.
	EnvController = "WNC_CONTROLLER"
	// EnvAccessToken supplies --access-token, the one token applied to every host
	// --controller names.
	EnvAccessToken = "WNC_ACCESS_TOKEN"
	// EnvUsername supplies --username of generate-token.
	EnvUsername = "WNC_USERNAME"
	// EnvPassword supplies --password of generate-token. Preferring it to the flag
	// keeps the credential out of the process arguments.
	EnvPassword = "WNC_PASSWORD"
)

Environment variables the flags fall back to.

View Source
const ColumnsAll = "all"

ColumnsAll is the --columns value that, given alone, selects every key of the view.

View Source
const DefaultLogLevel = "warning"

DefaultLogLevel shows a run's warnings and its failures. Nothing emits at Info.

View Source
const DefaultTimeout = 60 * time.Second

DefaultTimeout bounds one request: internal/wnc passes it to sdk.WithTimeout, which sets it as http.Client.Timeout. The wall-clock ceiling of a run is this times the number of sequential reads a command makes per controller.

View Source
const EnvConfig = "WNC_CONFIG"

EnvConfig names the environment variable that selects the configuration file.

Variables

This section is empty.

Functions

func ControllersFromEnv

func ControllersFromEnv() []string

ControllersFromEnv splits EnvController on commas, which is the only list form one variable can carry. An unset or empty variable yields no hosts.

func DefaultPath

func DefaultPath() string

DefaultPath is the file consulted when neither the flag nor the environment names one.

func NormalizeTagName

func NormalizeTagName(kind, s string) (string, error)

NormalizeTagName checks a tag name against the pattern the key leaf declares, `[!-~]([ -~]*[!-~])?`: printable ASCII throughout, with no leading or trailing space. The SDK repeats the same checks, but only once a client exists, which is one layer too late.

func Path

func Path(flagValue string) (path string, explicit bool)

Path picks the configuration file. The value passed in is the --config flag, which urfave has already filled from WNC_CONFIG, so the environment is not consulted twice. The bool reports whether the choice was explicit, which decides whether a missing file is an error.

func ResolveLogLevel

func ResolveLogLevel(cmd *cli.Command, file File, allowed []string) (string, error)

ResolveLogLevel merges the log level. The root reads it before any subcommand runs, so the file's value reaches the logger that reports the rest of the run.

func ResolveRadio

func ResolveRadio(cmd *cli.Command) (string, error)

ResolveRadio validates the band filter. An unset filter is the empty string, which selects every band.

func ValidateAuthority

func ValidateAuthority(a string) error

ValidateAuthority runs at parse time, so a malformed host is a usage fault at exit 2 before a client exists. '@' is refused here because the SDK's own check quotes the element it rejects, and neither a hostname nor a port may hold one, so nothing legal is turned away.

Types

type Controller

type Controller struct {
	Name *string `json:"name"`
	Host *string `json:"host"`
	Note *string `json:"note"`
}

Controller is one entry of the file's controllers array. Name labels the rows a controller produced. Note carries an operational remark, because JSON has no comments and a rejected unknown key leaves nowhere else to put one.

type Dur

type Dur time.Duration

Dur decodes a Go duration string such as "30s". Going through TextUnmarshaler also rejects a bare integer, which a numeric decode would read as nanoseconds. A json format tag is no way out: encoding/json/v2 shipped without `format`, so a field carrying one fails the decode of its whole struct whatever the field's type.

func (Dur) Duration

func (d Dur) Duration() time.Duration

func (*Dur) UnmarshalText

func (d *Dur) UnmarshalText(b []byte) error

UnmarshalText decodes the duration. A non-string JSON value never reaches here, so a numeric form cannot be tolerated in this method.

type File

type File struct {
	Note     *string `json:"note"`
	Timeout  *Dur    `json:"timeout"`
	Insecure *bool   `json:"insecure"`
	Format   *string `json:"format"`
	Pretty   *bool   `json:"pretty"`
	LogLevel *string `json:"log_level"`
	// Token is the one Basic auth token every controller in the file is read with. It is
	// file-wide rather than per entry, so the file holds one secret however many hosts it lists.
	Token       *string      `json:"token"`
	Controllers []Controller `json:"controllers"`
}

File mirrors the on-disk configuration. Every scalar field is a pointer so a key the file never set stays distinguishable from one set to a zero value, which lets a flag default win only where the file is genuinely silent.

func Load

func Load(path string, explicit bool, warn func(string)) (File, error)

Load reads the configuration file, and warn receives an advisory that does not stop the run. A missing file is an error only when the path was chosen explicitly, and the strict decode rejects an unknown key, a duplicate, a case-differing key, a comment and a trailing comma.

type Settings

type Settings struct {
	Controllers []Target
	Timeout     time.Duration
	Insecure    bool
	Format      string
	Pretty      bool
	SortBy      string
	SortOrder   string
	Columns     []string
}

Settings is the resolved configuration one command acts on.

func Resolve

func Resolve(
	cmd *cli.Command, file File, sortKeys []string, defaultSortBy string, defaultColumns []string,
) (Settings, error)

Resolve merges one show command's settings. Precedence is the flag or its environment variable, then the file, then the flag's own default: urfave marks an environment-sourced flag as set, so IsSet covers both of the first two.

func ResolveExec

func ResolveExec(cmd *cli.Command, file File) (Settings, error)

ResolveExec merges the settings an action needs. It is separate from Resolve rather than a call into it. An action declares none of the output or sort flags, so reading them through a command that never defined them would tie the exec tree to defaults only a show command validates.

func (Settings) Descending

func (s Settings) Descending() bool

type Target

type Target struct {
	Name  string
	Host  string
	Token string
}

Target is one controller a run queries. Host is the authority alone: the SDK forces https and checks the same forms later, so validating here turns a fault into a usage fault.

func ParseControllers

func ParseControllers(hosts []string, token string) ([]Target, error)

ParseControllers validates host[:port] elements and pairs each with the one token the caller resolved. An element carries no token of its own, so a forgotten one cannot leave the port occupying its place.

func TargetsFromFile

func TargetsFromFile(entries []Controller, token string) ([]Target, error)

TargetsFromFile converts the file's controllers array and pairs every entry with the file's one token. A file entry may carry a display name. Without one the authority labels the rows, matching what the flag produces.

func ValidateFile

func ValidateFile(file File, logLevels []string) ([]Target, error)

ValidateFile checks the parts of a configuration file that only a show command would otherwise reach, and returns the controllers it declares. --dry-run reports on this.

Jump to

Keyboard shortcuts

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