Add local and NetBox server notes and improve reliability
Release / release (push) Successful in 6m52s
Release / release (push) Successful in 6m52s
This commit is contained in:
1 parent
2852dff2c4
commit
12cc64fdd9
17 files changed
+848
-83
No files matched your search
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/cache"
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/config"
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/netbox"
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/notes"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func notesCmd() *cobra.Command {
|
||||
var remote bool
|
||||
var kind string
|
||||
cmd := &cobra.Command{Use: "notes", Short: "Read and write server notes (local by default)"}
|
||||
cmd.PersistentFlags().BoolVar(&remote, "netbox", false, "Use the NetBox comments field instead of local notes")
|
||||
cmd.PersistentFlags().StringVar(&kind, "kind", "", "Host kind: device or vm (required for uncached local hosts)")
|
||||
for _, action := range []string{"show", "set", "append"} {
|
||||
sub := &cobra.Command{Use: action + " <host> [text]", Short: action + " a server note", Args: cobra.RangeArgs(1, 2)}
|
||||
if action == "show" {
|
||||
sub.Args = cobra.ExactArgs(1)
|
||||
}
|
||||
sub.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
if kind != "" && kind != "vm" && kind != "device" {
|
||||
return fmt.Errorf("invalid kind %q", kind)
|
||||
}
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var client *netbox.Client
|
||||
if cfg.NetBox.URL != "" {
|
||||
client = netbox.NewClient(cfg.NetBox.URL, cfg.NetBox.Token, cfg.NetBox.TokenVersion)
|
||||
}
|
||||
host := netbox.HostEntry{Name: args[0], Kind: kind}
|
||||
c := cache.New(cfg.Cache.Path, cfg.Cache.TTL)
|
||||
if err := c.Load(); err != nil {
|
||||
return err
|
||||
}
|
||||
var cached []cache.Entry
|
||||
if !remote {
|
||||
cached = c.All()
|
||||
}
|
||||
for _, entry := range cached {
|
||||
if strings.EqualFold(entry.Name, host.Name) && (kind == "" || kind == entry.Kind) {
|
||||
host.Name = entry.Name
|
||||
host.Kind = entry.Kind
|
||||
break
|
||||
}
|
||||
}
|
||||
if !remote && host.Kind == "" {
|
||||
return fmt.Errorf("host is not cached; specify --kind device or --kind vm")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(cmd.Context(), 20*time.Second)
|
||||
defer cancel()
|
||||
service := notes.New(cfg.NetBox.URL, client)
|
||||
note, err := service.Read(ctx, host, remote)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if action == "show" {
|
||||
_, err := fmt.Fprint(cmd.OutOrStdout(), note.Text)
|
||||
return err
|
||||
}
|
||||
var text string
|
||||
if len(args) == 2 {
|
||||
text = args[1]
|
||||
} else {
|
||||
data, err := io.ReadAll(io.LimitReader(cmd.InOrStdin(), 1024*1024+1))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) > 1024*1024 {
|
||||
return fmt.Errorf("note exceeds 1 MiB")
|
||||
}
|
||||
text = string(data)
|
||||
}
|
||||
if action == "append" && note.Text != "" {
|
||||
note.Text = strings.TrimRight(note.Text, "\n") + "\n" + text
|
||||
} else {
|
||||
note.Text = text
|
||||
}
|
||||
return service.Write(ctx, note, remote)
|
||||
}
|
||||
cmd.AddCommand(sub)
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
Reference in new issue
Block a user