mirror of
https://github.com/OliveTin/OliveTin
synced 2025-12-12 09:05:39 +00:00
* feature: Execute actions on startup. Externalize the executor and add tags to logs. * fmt: Codestyle fixes
136 lines
3.3 KiB
Go
136 lines
3.3 KiB
Go
package grpcapi
|
|
|
|
import (
|
|
ctx "context"
|
|
pb "github.com/OliveTin/OliveTin/gen/grpc"
|
|
log "github.com/sirupsen/logrus"
|
|
"google.golang.org/grpc"
|
|
|
|
"net"
|
|
|
|
acl "github.com/OliveTin/OliveTin/internal/acl"
|
|
config "github.com/OliveTin/OliveTin/internal/config"
|
|
executor "github.com/OliveTin/OliveTin/internal/executor"
|
|
)
|
|
|
|
var (
|
|
cfg *config.Config
|
|
)
|
|
|
|
type oliveTinAPI struct {
|
|
pb.UnimplementedOliveTinApiServer
|
|
|
|
executor *executor.Executor
|
|
}
|
|
|
|
func (api *oliveTinAPI) StartAction(ctx ctx.Context, req *pb.StartActionRequest) (*pb.StartActionResponse, error) {
|
|
args := make(map[string]string)
|
|
|
|
log.Debugf("SA %v", req)
|
|
|
|
for _, arg := range req.Arguments {
|
|
args[arg.Name] = arg.Value
|
|
}
|
|
|
|
execReq := executor.ExecutionRequest{
|
|
ActionName: req.ActionName,
|
|
Arguments: args,
|
|
AuthenticatedUser: acl.UserFromContext(ctx, cfg),
|
|
Cfg: cfg,
|
|
}
|
|
|
|
return api.executor.ExecRequest(&execReq), nil
|
|
}
|
|
|
|
func (api *oliveTinAPI) GetDashboardComponents(ctx ctx.Context, req *pb.GetDashboardComponentsRequest) (*pb.GetDashboardComponentsResponse, error) {
|
|
user := acl.UserFromContext(ctx, cfg)
|
|
|
|
res := actionsCfgToPb(cfg.Actions, user)
|
|
|
|
if len(res.Actions) == 0 {
|
|
log.Warn("Zero actions found - check that you have some actions defined, with a view permission")
|
|
}
|
|
|
|
log.Debugf("GetDashboardComponents: %v", res)
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (api *oliveTinAPI) GetLogs(ctx ctx.Context, req *pb.GetLogsRequest) (*pb.GetLogsResponse, error) {
|
|
ret := &pb.GetLogsResponse{}
|
|
|
|
// TODO Limit to 10 entries or something to prevent browser lag.
|
|
|
|
for _, logEntry := range api.executor.Logs {
|
|
ret.Logs = append(ret.Logs, &pb.LogEntry{
|
|
ActionTitle: logEntry.ActionTitle,
|
|
ActionIcon: logEntry.ActionIcon,
|
|
Datetime: logEntry.Datetime,
|
|
Stdout: logEntry.Stdout,
|
|
Stderr: logEntry.Stderr,
|
|
TimedOut: logEntry.TimedOut,
|
|
ExitCode: logEntry.ExitCode,
|
|
Tags: logEntry.Tags,
|
|
})
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
/*
|
|
This function is ONLY a helper for the UI - the arguments are validated properly
|
|
on the StartAction -> Executor chain. This is here basically to provide helpful
|
|
error messages more quickly before starting the action.
|
|
*/
|
|
func (api *oliveTinAPI) ValidateArgumentType(ctx ctx.Context, req *pb.ValidateArgumentTypeRequest) (*pb.ValidateArgumentTypeResponse, error) {
|
|
err := executor.TypeSafetyCheck("", req.Value, req.Type)
|
|
desc := ""
|
|
|
|
if err != nil {
|
|
desc = err.Error()
|
|
}
|
|
|
|
return &pb.ValidateArgumentTypeResponse{
|
|
Valid: err == nil,
|
|
Description: desc,
|
|
}, nil
|
|
}
|
|
|
|
func (api *oliveTinAPI) WhoAmI(ctx ctx.Context, req *pb.WhoAmIRequest) (*pb.WhoAmIResponse, error) {
|
|
user := acl.UserFromContext(ctx, cfg)
|
|
|
|
res := &pb.WhoAmIResponse{
|
|
AuthenticatedUser: user.Username,
|
|
}
|
|
|
|
log.Warnf("usergroup: %v", user.Usergroup)
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// Start will start the GRPC API.
|
|
func Start(globalConfig *config.Config, ex *executor.Executor) {
|
|
cfg = globalConfig
|
|
|
|
lis, err := net.Listen("tcp", cfg.ListenAddressGrpcActions)
|
|
|
|
if err != nil {
|
|
log.Fatalf("Failed to listen - %v", err)
|
|
}
|
|
|
|
grpcServer := grpc.NewServer()
|
|
pb.RegisterOliveTinApiServer(grpcServer, newServer(ex))
|
|
|
|
err = grpcServer.Serve(lis)
|
|
|
|
if err != nil {
|
|
log.Fatalf("Could not start gRPC Server - %v", err)
|
|
}
|
|
}
|
|
|
|
func newServer(ex *executor.Executor) *oliveTinAPI {
|
|
server := oliveTinAPI{}
|
|
server.executor = ex
|
|
return &server
|
|
}
|