Files
backy/pkg/backy/lineinfile.go
Andrew Woodlee 0d6a13c1cf
Some checks failed
ci/woodpecker/push/go-lint Pipeline failed
ci/woodpecker/push/publish-docs Pipeline was successful
Cmd Type script now correctly appends arguments
2025-11-15 17:37:17 -06:00

134 lines
2.9 KiB
Go
Executable File

package backy
import (
"bufio"
"bytes"
"fmt"
"io"
"regexp"
"strings"
"golang.org/x/crypto/ssh"
)
func sshConnect(user, password, host string, port int) (*ssh.Client, error) {
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
addr := fmt.Sprintf("%s:%d", host, port)
return ssh.Dial("tcp", addr, config)
}
func sshReadFile(client *ssh.Client, remotePath string) (string, error) {
session, err := client.NewSession()
if err != nil {
return "", err
}
defer session.Close()
var b bytes.Buffer
session.Stdout = &b
if err := session.Run(fmt.Sprintf("cat %s", remotePath)); err != nil {
return "", err
}
return b.String(), nil
}
func sshWriteFile(client *ssh.Client, remotePath, content string) error {
session, err := client.NewSession()
if err != nil {
return err
}
defer session.Close()
stdin, err := session.StdinPipe()
if err != nil {
return err
}
go func() {
defer stdin.Close()
io.WriteString(stdin, content)
}()
cmd := fmt.Sprintf("cat > %s", remotePath)
return session.Run(cmd)
}
func lineInString(content, regexpPattern, line string) string {
scanner := bufio.NewScanner(strings.NewReader(content))
var lines []string
found := false
re := regexp.MustCompile(regexpPattern)
for scanner.Scan() {
l := scanner.Text()
if re.MatchString(l) {
found = true
lines = append(lines, line)
} else {
lines = append(lines, l)
}
}
if !found {
lines = append(lines, line)
}
return strings.Join(lines, "\n") + "\n"
}
func Call() {
user := "youruser"
password := "yourpassword"
host := "yourhost"
port := 22
remotePath := "/path/to/remote/file"
client, err := sshConnect(user, password, host, port)
if err != nil {
fmt.Println("SSH connection error:", err)
return
}
defer client.Close()
content, err := sshReadFile(client, remotePath)
if err != nil {
fmt.Println("Read error:", err)
return
}
newContent := lineInString(content, "^foo=", "foo=bar")
if err := sshWriteFile(client, remotePath, newContent); err != nil {
fmt.Println("Write error:", err)
return
}
fmt.Println("Line updated successfully over SSH.")
}
type LineInFile struct {
RemotePath string // Path to the remote file
Pattern string // Regex pattern to match lines
Line string // Line to insert or replace
InsertAfter bool // If true, insert after matched line; else replace
User string // SSH username
Password string // SSH password (use key for production)
Host string // SSH host
Port int // SSH port
regexCompiled *regexp.Regexp // Compiled regex (internal use)
}
// CompileRegex compiles the regex pattern for later use
func (l *LineInFile) CompileRegex() error {
re, err := regexp.Compile(l.Pattern)
if err != nil {
return err
}
l.regexCompiled = re
return nil
}