orama/pkg/cli/remotessh/config.go
anonpenguin23 6898f47e2e Replace sshpass password auth with RootWallet SSH keys
Replaces plaintext password-based SSH authentication (sshpass) across
the entire Go CLI with wallet-derived ed25519 keys via RootWallet.

- Add `rw vault ssh agent-load` command to RootWallet CLI for SSH
  agent forwarding in push fanout
- Create wallet.go bridge: PrepareNodeKeys resolves keys from `rw
  vault ssh get --priv`, writes temp PEMs (0600), zero-overwrites
  on cleanup
- Remove Password field from Node struct, update config parser to
  new 3-field format (env|user@host|role)
- Remove all sshpass branches from inspector/ssh.go and
  remotessh/ssh.go, require SSHKey on all SSH paths
- Add WithAgentForward() option to RunSSHStreaming for hub fanout
- Add PrepareNodeKeys + defer cleanup to all 7 entry points:
  inspect, monitor, push, upgrade, clean, recover, install
- Update push fanout to use SSH agent forwarding instead of sshpass
  on hub
- Delete install/ssh.go duplicate, replace with remotessh calls
- Create nodes.conf from remote-nodes.conf (topology only, no
  secrets)
- Update all config defaults and help text from remote-nodes.conf
  to nodes.conf
- Use StrictHostKeyChecking=accept-new consistently everywhere
2026-02-24 17:24:16 +02:00

70 lines
1.7 KiB
Go

package remotessh
import (
"fmt"
"os"
"path/filepath"
"github.com/DeBrosOfficial/network/pkg/inspector"
)
// FindNodesConf searches for the nodes.conf file
// in common locations relative to the current directory or project root.
func FindNodesConf() string {
candidates := []string{
"scripts/nodes.conf",
"../scripts/nodes.conf",
"network/scripts/nodes.conf",
}
// Also check from home dir
home, _ := os.UserHomeDir()
if home != "" {
candidates = append(candidates, filepath.Join(home, ".orama", "nodes.conf"))
}
for _, c := range candidates {
if _, err := os.Stat(c); err == nil {
return c
}
}
return ""
}
// LoadEnvNodes loads all nodes for a given environment from nodes.conf.
// SSHKey fields are NOT set — caller must call PrepareNodeKeys() after this.
func LoadEnvNodes(env string) ([]inspector.Node, error) {
confPath := FindNodesConf()
if confPath == "" {
return nil, fmt.Errorf("nodes.conf not found (checked scripts/, ../scripts/, network/scripts/)")
}
nodes, err := inspector.LoadNodes(confPath)
if err != nil {
return nil, fmt.Errorf("failed to load %s: %w", confPath, err)
}
filtered := inspector.FilterByEnv(nodes, env)
if len(filtered) == 0 {
return nil, fmt.Errorf("no nodes found for environment %q in %s", env, confPath)
}
return filtered, nil
}
// PickHubNode selects the first node as the hub for fanout distribution.
func PickHubNode(nodes []inspector.Node) inspector.Node {
return nodes[0]
}
// FilterByIP returns nodes matching the given IP address.
func FilterByIP(nodes []inspector.Node, ip string) []inspector.Node {
var filtered []inspector.Node
for _, n := range nodes {
if n.Host == ip {
filtered = append(filtered, n)
}
}
return filtered
}