feat: config grouped by area, with per-provider timeouts and an update interval (#60)
Regroups the config, while there are no users to migrate: - `ui`: icons, sourcesView, collapseGroups, loadDelay, expiryWarningDays - `values`: revealTimeout, hideOnBlur, clipboardClear - `storage`: cache, history - `updates`: autoCheck (was updateCheck), autoCheckInterval (new, 24h by default), updateSources (was releases) - `providers.timeout` (was timeout), plus `timeout` on azure, databricks and repos overriding it for that provider; `--timeout` still sets them all - `sharing` (was share), in the config and in a repo's `.lazysecrets.yaml` docs/config.md and the pages naming these keys are updated. Reviewed-on: #60 Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
This commit was merged in pull request #60.
This commit is contained in:
1 parent
5cd6d90555
commit
10d1fc63c7
24 files changed
+308
-172
No files matched your search
+86
-54
@@ -19,44 +19,18 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Icons *bool `yaml:"icons"`
|
||||
ClipboardClear *time.Duration `yaml:"clipboardClear"`
|
||||
// RevealTimeout hides a revealed value after this long; 0s never.
|
||||
// Defaults to 60s.
|
||||
RevealTimeout *time.Duration `yaml:"revealTimeout"`
|
||||
// ExpiryWarningDays marks secrets, keys and certificates expiring
|
||||
// within this many days; 0 marks only expired ones. Defaults to 30.
|
||||
ExpiryWarningDays *int `yaml:"expiryWarningDays"`
|
||||
// HideOnBlur hides a revealed value when the terminal loses focus.
|
||||
// Defaults to true.
|
||||
HideOnBlur *bool `yaml:"hideOnBlur"`
|
||||
Timeout time.Duration `yaml:"timeout"`
|
||||
// LoadDelay is how long the cursor must rest on a row before its
|
||||
// contents load; 0s loads at once. Defaults to 150ms.
|
||||
LoadDelay *time.Duration `yaml:"loadDelay"`
|
||||
// SourcesView is "grouped" (default) or "flat"; ` + "`" + ` toggles it.
|
||||
SourcesView string `yaml:"sourcesView"`
|
||||
// History counts uses of items for the Recent list; defaults to true.
|
||||
History *bool `yaml:"history"`
|
||||
// UpdateCheck looks for a newer release once a day, in the
|
||||
// background; defaults to true. U and lazysecrets update work either
|
||||
// way.
|
||||
UpdateCheck *bool `yaml:"updateCheck"`
|
||||
// Releases are the repositories updates come from, tried in order:
|
||||
// on GitHub, or a Gitea or Forgejo server. Defaults to GitHub, then
|
||||
// git.kebcloud.no (update.DefaultServers).
|
||||
Releases []string `yaml:"releases"`
|
||||
// Cache keeps what was loaded (never values) between runs, so lists
|
||||
// show at once and refresh in the background; defaults to true.
|
||||
Cache *bool `yaml:"cache"`
|
||||
// CollapseGroups starts the Sources pane with its groups folded;
|
||||
// defaults to true.
|
||||
CollapseGroups *bool `yaml:"collapseGroups"`
|
||||
Providers Providers `yaml:"providers"`
|
||||
UI UI `yaml:"ui"`
|
||||
// Values keeps revealed and copied values from lingering.
|
||||
Values Values `yaml:"values"`
|
||||
// Storage is what's kept between runs.
|
||||
Storage Storage `yaml:"storage"`
|
||||
// Updates sets how lazysecrets looks for newer releases.
|
||||
Updates Updates `yaml:"updates"`
|
||||
Providers Providers `yaml:"providers"`
|
||||
// LinkHandler sets how lazysecrets:// links open; see linkhandler.
|
||||
LinkHandler LinkHandler `yaml:"linkHandler"`
|
||||
// Share sets how env files are shared; see package share.
|
||||
Share Share `yaml:"share"`
|
||||
// Sharing sets how env files are shared; see package share.
|
||||
Sharing Sharing `yaml:"sharing"`
|
||||
// CustomCommands run shell commands on the selected item; see
|
||||
// package commands.
|
||||
CustomCommands []commands.Command `yaml:"customCommands"`
|
||||
@@ -68,6 +42,52 @@ type Config struct {
|
||||
Theme map[string][]string `yaml:"theme"`
|
||||
}
|
||||
|
||||
type UI struct {
|
||||
Icons *bool `yaml:"icons"`
|
||||
// SourcesView is "grouped" (default) or "flat"; ` + "`" + ` toggles it.
|
||||
SourcesView string `yaml:"sourcesView"`
|
||||
// CollapseGroups starts the Sources pane with its groups folded;
|
||||
// defaults to true.
|
||||
CollapseGroups *bool `yaml:"collapseGroups"`
|
||||
// LoadDelay is how long the cursor must rest on a row before its
|
||||
// contents load; 0s loads at once. Defaults to 150ms.
|
||||
LoadDelay *time.Duration `yaml:"loadDelay"`
|
||||
// ExpiryWarningDays marks secrets, keys and certificates expiring
|
||||
// within this many days; 0 marks only expired ones. Defaults to 30.
|
||||
ExpiryWarningDays *int `yaml:"expiryWarningDays"`
|
||||
}
|
||||
|
||||
type Values struct {
|
||||
// RevealTimeout hides a revealed value after this long; 0s never.
|
||||
// Defaults to 60s.
|
||||
RevealTimeout *time.Duration `yaml:"revealTimeout"`
|
||||
// HideOnBlur hides a revealed value when the terminal loses focus.
|
||||
// Defaults to true.
|
||||
HideOnBlur *bool `yaml:"hideOnBlur"`
|
||||
ClipboardClear *time.Duration `yaml:"clipboardClear"`
|
||||
}
|
||||
|
||||
type Storage struct {
|
||||
// Cache keeps what was loaded (never values) between runs, so lists
|
||||
// show at once and refresh in the background; defaults to true.
|
||||
Cache *bool `yaml:"cache"`
|
||||
// History counts uses of items for the Recent list; defaults to true.
|
||||
History *bool `yaml:"history"`
|
||||
}
|
||||
|
||||
type Updates struct {
|
||||
// AutoCheck looks for a newer release in the background at startup,
|
||||
// at most once per AutoCheckInterval; defaults to true. U and
|
||||
// lazysecrets update work either way.
|
||||
AutoCheck *bool `yaml:"autoCheck"`
|
||||
// AutoCheckInterval defaults to 24h.
|
||||
AutoCheckInterval *time.Duration `yaml:"autoCheckInterval"`
|
||||
// UpdateSources are the repositories updates come from, tried in
|
||||
// order: on GitHub, or a Gitea or Forgejo server. Defaults to GitHub,
|
||||
// then git.kebcloud.no (update.DefaultServers).
|
||||
UpdateSources []string `yaml:"updateSources"`
|
||||
}
|
||||
|
||||
type LinkHandler struct {
|
||||
// Terminal to open links in, overriding the one handler install
|
||||
// detected: kitty, ghostty, wezterm, iterm2, terminal, alacritty,
|
||||
@@ -85,7 +105,7 @@ type LinkHandler struct {
|
||||
Prompt *bool `yaml:"prompt"`
|
||||
}
|
||||
|
||||
type Share struct {
|
||||
type Sharing struct {
|
||||
// Key is the secret whose value encrypts shared files (its
|
||||
// lazysecrets:// link, Key Vault URL or reference), for repos whose
|
||||
// .lazysecrets.yaml doesn't name one.
|
||||
@@ -103,15 +123,20 @@ type KeyRules struct {
|
||||
}
|
||||
|
||||
type Providers struct {
|
||||
Azure Azure `yaml:"azure"`
|
||||
Databricks Databricks `yaml:"databricks"`
|
||||
Repos Repos `yaml:"repos"`
|
||||
// Timeout bounds each backend request; defaults to 30s. Each
|
||||
// provider's own timeout overrides it for that provider.
|
||||
Timeout time.Duration `yaml:"timeout"`
|
||||
Azure Azure `yaml:"azure"`
|
||||
Databricks Databricks `yaml:"databricks"`
|
||||
Repos Repos `yaml:"repos"`
|
||||
}
|
||||
|
||||
// Repos are git repositories' secret files (SOPS, .env). Inside a repo,
|
||||
// that repo is the only one shown; elsewhere, the ones in Paths and under
|
||||
// Roots.
|
||||
type Repos struct {
|
||||
// Timeout overrides providers.timeout for these requests.
|
||||
Timeout time.Duration `yaml:"timeout"`
|
||||
// Enabled defaults to true.
|
||||
Enabled *bool `yaml:"enabled"`
|
||||
Paths []string `yaml:"paths"`
|
||||
@@ -126,6 +151,8 @@ type Repos struct {
|
||||
}
|
||||
|
||||
type Azure struct {
|
||||
// Timeout overrides providers.timeout for these requests.
|
||||
Timeout time.Duration `yaml:"timeout"`
|
||||
// Enabled defaults to true.
|
||||
Enabled *bool `yaml:"enabled"`
|
||||
// HideSubscriptions lists subscriptions to leave out, by name or ID.
|
||||
@@ -136,6 +163,8 @@ type Azure struct {
|
||||
}
|
||||
|
||||
type Databricks struct {
|
||||
// Timeout overrides providers.timeout for these requests.
|
||||
Timeout time.Duration `yaml:"timeout"`
|
||||
// Enabled defaults to true.
|
||||
Enabled *bool `yaml:"enabled"`
|
||||
HideProfiles []string `yaml:"hideProfiles"`
|
||||
@@ -222,35 +251,38 @@ func decodeInto(c *Config, path string) error {
|
||||
}
|
||||
|
||||
func (c Config) validate(path string) error {
|
||||
if v := c.SourcesView; v != "" && v != "grouped" && v != "flat" {
|
||||
return fmt.Errorf("%s: sourcesView: %q is not grouped or flat", path, v)
|
||||
if v := c.UI.SourcesView; v != "" && v != "grouped" && v != "flat" {
|
||||
return fmt.Errorf("%s: ui.sourcesView: %q is not grouped or flat", path, v)
|
||||
}
|
||||
for _, cmd := range c.CustomCommands {
|
||||
if err := cmd.Validate(); err != nil {
|
||||
return fmt.Errorf("%s: %w", path, err)
|
||||
}
|
||||
}
|
||||
if d := c.ExpiryWarningDays; d != nil && *d < 0 {
|
||||
return fmt.Errorf("%s: expiryWarningDays: %d is negative", path, *d)
|
||||
if d := c.UI.ExpiryWarningDays; d != nil && *d < 0 {
|
||||
return fmt.Errorf("%s: ui.expiryWarningDays: %d is negative", path, *d)
|
||||
}
|
||||
if d := c.LoadDelay; d != nil && (*d < 0 || *d > 5*time.Second) {
|
||||
return fmt.Errorf("%s: loadDelay: %s is not between 0s and 5s", path, *d)
|
||||
if d := c.UI.LoadDelay; d != nil && (*d < 0 || *d > 5*time.Second) {
|
||||
return fmt.Errorf("%s: ui.loadDelay: %s is not between 0s and 5s", path, *d)
|
||||
}
|
||||
for i, r := range c.Releases {
|
||||
if d := c.Updates.AutoCheckInterval; d != nil && *d <= 0 {
|
||||
return fmt.Errorf("%s: updates.autoCheckInterval: %s is not positive (autoCheck: false turns it off)", path, *d)
|
||||
}
|
||||
for i, r := range c.Updates.UpdateSources {
|
||||
if _, err := update.API(r); err != nil || !strings.HasPrefix(r, "https://") {
|
||||
return fmt.Errorf("%s: releases[%d]: %q is not an https:// repository address, like %s", path, i, r, update.GitHubRepo)
|
||||
return fmt.Errorf("%s: updates.updateSources[%d]: %q is not an https:// repository address, like %s", path, i, r, update.GitHubRepo)
|
||||
}
|
||||
}
|
||||
if k := c.Share.Key; k != "" {
|
||||
if k := c.Sharing.Key; k != "" {
|
||||
if _, err := share.ParseKey(k); err != nil {
|
||||
return fmt.Errorf("%s: share.key: %w", path, err)
|
||||
return fmt.Errorf("%s: sharing.key: %w", path, err)
|
||||
}
|
||||
}
|
||||
if n := c.Share.KeyRules.MinLength; n != 0 && n < 16 {
|
||||
return fmt.Errorf("%s: share.keyRules.minLength: %d is under 16", path, n)
|
||||
if n := c.Sharing.KeyRules.MinLength; n != 0 && n < 16 {
|
||||
return fmt.Errorf("%s: sharing.keyRules.minLength: %d is under 16", path, n)
|
||||
}
|
||||
if n := c.Share.KeyRules.MinClasses; n < 0 || n > 4 {
|
||||
return fmt.Errorf("%s: share.keyRules.minClasses: %d is not between 1 and 4", path, n)
|
||||
if n := c.Sharing.KeyRules.MinClasses; n < 0 || n > 4 {
|
||||
return fmt.Errorf("%s: sharing.keyRules.minClasses: %d is not between 1 and 4", path, n)
|
||||
}
|
||||
for i, v := range c.Providers.Azure.Vaults {
|
||||
if !strings.HasPrefix(v, "https://") {
|
||||
|
||||
Reference in new issue
Block a user