94 lines
2.7 KiB
Go
94 lines
2.7 KiB
Go
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
|
|
}
|