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
- func ControllersFromEnv() []string
- func DefaultPath() string
- func NormalizeTagName(kind, s string) (string, error)
- func Path(flagValue string) (path string, explicit bool)
- func ResolveLogLevel(cmd *cli.Command, file File, allowed []string) (string, error)
- func ResolveRadio(cmd *cli.Command) (string, error)
- func ValidateAuthority(a string) error
- type Controller
- type Dur
- type File
- type Settings
- type Target
Constants ¶
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.
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.
const ( FormatTable = "table" FormatJSON = "json" )
const ( OrderAsc = "asc" OrderDesc = "desc" )
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.
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.
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.
const ColumnsAll = "all"
ColumnsAll is the --columns value that, given alone, selects every key of the view.
const DefaultLogLevel = "warning"
DefaultLogLevel shows a run's warnings and its failures. Nothing emits at Info.
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.
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 ¶
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 ¶
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 ¶
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 ¶
ResolveRadio validates the band filter. An unset filter is the empty string, which selects every band.
func ValidateAuthority ¶
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 ¶
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) UnmarshalText ¶
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.
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 ¶
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 ¶
type Target ¶
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 ¶
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.