refactor some code
This commit is contained in:
parent
37f411ec55
commit
58d1af4f84
12 changed files with 47 additions and 28 deletions
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
|
|
@ -39,6 +39,11 @@ jobs:
|
|||
- name: Vet
|
||||
run: go vet ./...
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Test
|
||||
run: go test -v ./...
|
||||
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,6 +1,7 @@
|
|||
# Go
|
||||
towerops-agent
|
||||
*.test
|
||||
cover.out
|
||||
|
||||
# Database files
|
||||
*.db
|
||||
|
|
|
|||
2
agent.go
2
agent.go
|
|
@ -65,7 +65,7 @@ func runSession(ctx context.Context, baseURL, token string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("connect: %w", err)
|
||||
}
|
||||
defer ws.Close()
|
||||
defer func() { _ = ws.Close() }()
|
||||
|
||||
agentID := fmt.Sprintf("agent-%d", time.Now().Unix())
|
||||
topic := "agent:" + agentID
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = [
|
||||
pkgs.go
|
||||
pkgs.golangci-lint
|
||||
pkgs.protobuf
|
||||
pkgs.protoc-gen-go
|
||||
pkgs.git
|
||||
|
|
|
|||
13
mikrotik.go
13
mikrotik.go
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -42,7 +43,7 @@ func mikrotikConnect(ip string, port uint32, username, password string, useSSL b
|
|||
NetDialer: &net.Dialer{Timeout: mikrotikConnTimeout},
|
||||
Config: &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS12},
|
||||
}
|
||||
conn, err = dialer.DialContext(nil, "tcp", addr)
|
||||
conn, err = dialer.DialContext(context.Background(), "tcp", addr)
|
||||
} else {
|
||||
conn, err = net.DialTimeout("tcp", addr, mikrotikConnTimeout)
|
||||
}
|
||||
|
|
@ -55,11 +56,11 @@ func mikrotikConnect(ip string, port uint32, username, password string, useSSL b
|
|||
// Authenticate
|
||||
resp, err := c.execute("/login", map[string]string{"name": username, "password": password})
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
return nil, fmt.Errorf("auth: %w", err)
|
||||
}
|
||||
if resp.err != "" {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
return nil, fmt.Errorf("auth failed: %s", resp.err)
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ func (c *mikrotikClient) execute(command string, args map[string]string) (*mikro
|
|||
}
|
||||
|
||||
func (c *mikrotikClient) close() error {
|
||||
c.execute("/quit", nil) // best-effort
|
||||
_, _ = c.execute("/quit", nil) // best-effort
|
||||
return c.conn.Close()
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +146,7 @@ func (c *mikrotikClient) readSentence() ([]string, error) {
|
|||
var words []string
|
||||
for {
|
||||
if tc, ok := c.conn.(net.Conn); ok {
|
||||
tc.SetReadDeadline(time.Now().Add(mikrotikReadTimeout))
|
||||
_ = tc.SetReadDeadline(time.Now().Add(mikrotikReadTimeout))
|
||||
}
|
||||
word, err := c.readWord()
|
||||
if err != nil {
|
||||
|
|
@ -268,7 +269,7 @@ func executeMikrotikJob(job *pb.AgentJob, resultCh chan<- *pb.MikrotikResult) {
|
|||
}
|
||||
return
|
||||
}
|
||||
defer client.close()
|
||||
defer func() { _ = client.close() }()
|
||||
|
||||
var allSentences []*pb.MikrotikSentence
|
||||
var errorMessage string
|
||||
|
|
|
|||
11
snmp.go
11
snmp.go
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gosnmp/gosnmp"
|
||||
"github.com/towerops-app/towerops-agent/pb"
|
||||
|
|
@ -22,7 +23,7 @@ func executeSnmpJob(job *pb.AgentJob, resultCh chan<- *pb.SnmpResult) {
|
|||
slog.Error("snmp connect", "job_id", job.JobId, "device", dev.Ip, "error", err)
|
||||
return
|
||||
}
|
||||
defer conn.Conn.Close()
|
||||
defer func() { _ = conn.Conn.Close() }()
|
||||
|
||||
oidValues := make(map[string]string)
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ func executeCredentialTest(job *pb.AgentJob, resultCh chan<- *pb.CredentialTestR
|
|||
}
|
||||
return
|
||||
}
|
||||
defer conn.Conn.Close()
|
||||
defer func() { _ = conn.Conn.Close() }()
|
||||
|
||||
result, err := conn.Get([]string{"1.3.6.1.2.1.1.1.0"})
|
||||
if err != nil {
|
||||
|
|
@ -221,10 +222,12 @@ func snmpValueToString(pdu gosnmp.SnmpPDU) string {
|
|||
return fmt.Sprintf("%d", gosnmp.ToBigInt(pdu.Value).Int64())
|
||||
case gosnmp.OctetString:
|
||||
b := pdu.Value.([]byte)
|
||||
// Try UTF-8 first
|
||||
if !utf8.Valid(b) {
|
||||
return formatHex(b)
|
||||
}
|
||||
// Check for non-printable control chars
|
||||
for _, c := range b {
|
||||
if c < 0x20 && c != '\n' && c != '\r' && c != '\t' {
|
||||
// Non-printable - return hex
|
||||
return formatHex(b)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,11 @@ func TestSnmpValueToString(t *testing.T) {
|
|||
pdu: gosnmp.SnmpPDU{Type: gosnmp.NoSuchObject, Value: nil},
|
||||
want: "null",
|
||||
},
|
||||
{
|
||||
name: "invalid utf8",
|
||||
pdu: gosnmp.SnmpPDU{Type: gosnmp.OctetString, Value: []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x80, 0xFE}},
|
||||
want: "48:65:6c:6c:6f:80:fe",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
|||
4
ssh.go
4
ssh.go
|
|
@ -23,13 +23,13 @@ func executeMikrotikBackup(ip string, port uint16, username, password string) (s
|
|||
if err != nil {
|
||||
return "", fmt.Errorf("ssh dial %s: %w", addr, err)
|
||||
}
|
||||
defer conn.Close()
|
||||
defer func() { _ = conn.Close() }()
|
||||
|
||||
session, err := conn.NewSession()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("ssh session: %w", err)
|
||||
}
|
||||
defer session.Close()
|
||||
defer func() { _ = session.Close() }()
|
||||
|
||||
output, err := session.CombinedOutput("/export compact")
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ func selfUpdate(downloadURL, expectedChecksum string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("download: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("download failed: status %d", resp.StatusCode)
|
||||
|
|
@ -52,7 +52,7 @@ func selfUpdate(downloadURL, expectedChecksum string) error {
|
|||
|
||||
// Replace current binary
|
||||
if err := os.Rename(tempPath, currentExe); err != nil {
|
||||
os.Remove(tempPath)
|
||||
_ = os.Remove(tempPath)
|
||||
return fmt.Errorf("rename: %w", err)
|
||||
}
|
||||
slog.Info("binary replaced", "path", currentExe)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func TestSelfUpdateBadURL(t *testing.T) {
|
|||
|
||||
func TestSelfUpdateChecksumMismatch(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("fake binary"))
|
||||
_, _ = w.Write([]byte("fake binary"))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ func TestSelfUpdateChecksumMatch(t *testing.T) {
|
|||
checksum := fmt.Sprintf("%x", sha256.Sum256(body))
|
||||
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write(body)
|
||||
_, _ = w.Write(body)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
|
|
|
|||
16
websocket.go
16
websocket.go
|
|
@ -57,7 +57,7 @@ func WSDial(rawURL string) (*WSConn, error) {
|
|||
// Generate random key for Sec-WebSocket-Key
|
||||
keyBytes := make([]byte, 16)
|
||||
if _, err := rand.Read(keyBytes); err != nil {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
return nil, fmt.Errorf("generate key: %w", err)
|
||||
}
|
||||
key := base64.StdEncoding.EncodeToString(keyBytes)
|
||||
|
|
@ -67,7 +67,7 @@ func WSDial(rawURL string) (*WSConn, error) {
|
|||
path, u.Host, key)
|
||||
|
||||
if _, err := conn.Write([]byte(req)); err != nil {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
return nil, fmt.Errorf("write handshake: %w", err)
|
||||
}
|
||||
|
||||
|
|
@ -75,12 +75,12 @@ func WSDial(rawURL string) (*WSConn, error) {
|
|||
buf := make([]byte, 4096)
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
return nil, fmt.Errorf("read handshake: %w", err)
|
||||
}
|
||||
resp := string(buf[:n])
|
||||
if !strings.Contains(resp, "101") {
|
||||
conn.Close()
|
||||
_ = conn.Close()
|
||||
return nil, fmt.Errorf("handshake failed: %s", strings.SplitN(resp, "\r\n", 2)[0])
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ func (ws *WSConn) ReadMessage() ([]byte, int, error) {
|
|||
return nil, 0, fmt.Errorf("pong: %w", err)
|
||||
}
|
||||
case opClose:
|
||||
ws.writeFrame(opClose, nil) // best-effort close reply
|
||||
_ = ws.writeFrame(opClose, nil) // best-effort close reply
|
||||
return nil, opClose, io.EOF
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ func (ws *WSConn) WriteText(data []byte) error {
|
|||
|
||||
// Close sends a close frame and closes the underlying connection.
|
||||
func (ws *WSConn) Close() error {
|
||||
ws.writeFrame(opClose, nil) // best-effort
|
||||
_ = ws.writeFrame(opClose, nil) // best-effort
|
||||
return ws.conn.Close()
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ func (ws *WSConn) writeFrame(opcode int, payload []byte) error {
|
|||
// Max header: 2 + 8 + 4 (mask) = 14 bytes
|
||||
header := make([]byte, 2, 14)
|
||||
header[0] = 0x80 | byte(opcode) // FIN + opcode
|
||||
header[1] = 0x80 // masked (client must mask)
|
||||
header[1] = 0x80 // masked (client must mask)
|
||||
|
||||
switch {
|
||||
case length <= 125:
|
||||
|
|
@ -194,7 +194,7 @@ func (ws *WSConn) writeFrame(opcode int, payload []byte) error {
|
|||
|
||||
// Generate mask key
|
||||
maskKey := make([]byte, 4)
|
||||
rand.Read(maskKey)
|
||||
_, _ = rand.Read(maskKey)
|
||||
header = append(header, maskKey...)
|
||||
|
||||
// Mask payload
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ type captureWriter struct {
|
|||
written []byte
|
||||
}
|
||||
|
||||
func (c *captureWriter) Read(p []byte) (int, error) { return c.Reader.Read(p) }
|
||||
func (c *captureWriter) Write(p []byte) (int, error) { c.written = append(c.written, p...); return len(p), nil }
|
||||
func (c *captureWriter) Close() error { return nil }
|
||||
func (c *captureWriter) Read(p []byte) (int, error) { return c.Reader.Read(p) }
|
||||
func (c *captureWriter) Write(p []byte) (int, error) {
|
||||
c.written = append(c.written, p...)
|
||||
return len(p), nil
|
||||
}
|
||||
func (c *captureWriter) Close() error { return nil }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue