package main import ( "connectrpc.com/connect" "context" "fmt" "log" homelabv1 "pwa-homelab-mon/gen/homelab/v1" "strings" ) // --- content RPC --- func (s *server) ListContent(ctx context.Context, _ *connect.Request[homelabv1.ListContentRequest]) (*connect.Response[homelabv1.ListContentResponse], error) { resp := &homelabv1.ListContentResponse{} for _, l := range s.cfg.Links { resp.Links = append(resp.Links, &homelabv1.Link{Name: l.Name, Url: l.URL}) } for i := range s.cfg.Monitor { it := &s.cfg.Monitor[i] m := &homelabv1.Monitor{Name: it.Name} if d, ok := s.monVals.Load(it.Name); ok { md := d.(*monData) m.Percentage, m.Stats = md.percentage, md.stats } resp.Monitors = append(resp.Monitors, m) } for i := range s.cfg.Exec { it := &s.cfg.Exec[i] resp.Exec = append(resp.Exec, &homelabv1.Item{Name: it.Name, Args: int32(it.Args), ArgTypes: it.ArgTypes}) } resp.Services = s.services(ctx) return connect.NewResponse(resp), nil } func (s *server) RunScript(_ context.Context, req *connect.Request[homelabv1.RunScriptRequest]) (*connect.Response[homelabv1.RunScriptResponse], error) { it, ok := s.exec[req.Msg.GetName()] if !ok { return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("no exec item %q", req.Msg.GetName())) } if len(req.Msg.GetArgs()) != it.Args { return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("%q takes %d args, got %d", it.Name, it.Args, len(req.Msg.GetArgs()))) } out, err := runScript(it.Script, req.Msg.GetArgs()...) if err != nil { log.Printf("script %s args=%v: ERROR %v", it.Name, req.Msg.GetArgs(), err) return nil, connect.NewError(connect.CodeInternal, err) } log.Printf("script %s args=%v -> %s", it.Name, req.Msg.GetArgs(), strings.TrimSpace(out)) return connect.NewResponse(&homelabv1.RunScriptResponse{Output: out}), nil }