fix: harden config loading and ssh addresses, stop resolver on API errors
- read netssh.yaml from the user config directory only, not from the working directory - refuse addresses from NetBox or the cache that are neither an IP address nor a hostname (ssh read "-oProxyCommand=…" as an option) - resolver chain stops at an API failure; only "no address" falls through to the next strategy - netssh --help and -h show netssh's help - start at most one background cache refresh per 5 minutes - validate the legacy netbox.url - page through all IP addresses of a host - CI: run format check, vet, and tests on pull requests and main - changelog for v0.0.25 Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
1 parent
6e80b733dc
commit
4287b7b650
19 files changed
+317
-30
No files matched your search
+19
-1
@@ -62,6 +62,16 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// ssh has neither option, so both can only mean netssh's own help.
|
||||
if args[0] == "--help" || args[0] == "-h" {
|
||||
root := rootCmd()
|
||||
root.SetArgs([]string{"help"})
|
||||
if err := root.Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if managedSubcommands[args[0]] {
|
||||
if err := rootCmd().Execute(); err != nil {
|
||||
os.Exit(1)
|
||||
@@ -320,6 +330,9 @@ func findSSHHost(ctx context.Context, client *netbox.Client, name string, domain
|
||||
|
||||
// connectHost applies the SSH options configured for the host and execs the client.
|
||||
func connectHost(cfg *config.Config, client internalssh.Client, flags internalssh.WrapperFlags, host resolvedHost, dests []int, args []string) {
|
||||
if !internalssh.ValidAddress(host.IP) {
|
||||
fatalf("refusing address %q for %s: not an IP address or hostname (check NetBox, or run netssh cache clear)", host.IP, host.Name)
|
||||
}
|
||||
opts := hostOptions(cfg, host)
|
||||
if len(flags.Forwards) > 0 {
|
||||
forwardArgs, err := internalssh.ForwardArgs(flags.Forwards, opts.Forwards)
|
||||
@@ -1000,6 +1013,9 @@ func hookUninstallCmd() *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
// refreshRetryInterval is the pause between background refresh attempts.
|
||||
const refreshRetryInterval = 5 * time.Minute
|
||||
|
||||
// maybeBackgroundRefresh starts a background `netssh cache refresh` if the cache
|
||||
// has not been fully refreshed within the last 24 hours.
|
||||
func maybeBackgroundRefresh(cfg *config.Config, c *cache.Cache) {
|
||||
@@ -1007,7 +1023,9 @@ func maybeBackgroundRefresh(cfg *config.Config, c *cache.Cache) {
|
||||
if !cfg.HasNetBox() || os.Getenv("NETSSH_NO_REFRESH") != "" {
|
||||
return
|
||||
}
|
||||
if !c.NeedsRefresh(24 * time.Hour) {
|
||||
// While NetBox is unreachable the cache stays stale; without the retry
|
||||
// interval every command and every new shell would start another refresh.
|
||||
if !c.ClaimRefresh(24*time.Hour, refreshRetryInterval) {
|
||||
return
|
||||
}
|
||||
self, err := os.Executable()
|
||||
|
||||
@@ -71,6 +71,7 @@ func buildUninstallPlan(cfg *config.Config, keepConfig bool) uninstallPlan {
|
||||
addPath(path)
|
||||
addPath(path + ".lock")
|
||||
addPath(filepath.Join(filepath.Dir(path), "last_refresh"))
|
||||
addPath(filepath.Join(filepath.Dir(path), "refresh_attempt"))
|
||||
if strings.HasPrefix(filepath.Base(filepath.Dir(path)), "instances-") {
|
||||
addPath(filepath.Dir(path))
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user