http-boot-config/config/main.go

161 lines
3.9 KiB
Go
Raw Normal View History

2023-08-13 14:20:55 +00:00
package main
2023-08-13 15:59:05 +00:00
import (
"context"
2023-08-13 15:59:05 +00:00
"errors"
"flag"
"fmt"
2023-08-13 15:59:05 +00:00
"io/fs"
2023-08-13 16:46:06 +00:00
"os"
2023-08-13 15:59:05 +00:00
"git.faercol.me/faercol/http-boot-config/config/logger"
"git.faercol.me/faercol/http-boot-config/config/prober"
"git.faercol.me/faercol/http-boot-config/config/remote"
"github.com/google/uuid"
2023-08-13 15:59:05 +00:00
)
2023-08-13 16:46:06 +00:00
type action int
const (
actionList action = iota
actionGetRemote
actionEnroll
2023-08-13 16:46:06 +00:00
actionUnknown
)
2023-08-13 15:59:05 +00:00
type cliArgs struct {
debug bool
colour bool
action action
id uuid.UUID
remoteAddr string
prettyPrint bool
name string
2023-08-13 16:46:06 +00:00
}
var defaultArgs cliArgs = cliArgs{
debug: false,
colour: true,
action: actionUnknown,
2023-08-13 15:59:05 +00:00
}
2023-08-13 16:46:06 +00:00
func parseArgs() (cliArgs, error) {
args := defaultArgs
var firstArg int
listFlagSet := flag.NewFlagSet("list", flag.ExitOnError)
getRemoteFlagSet := flag.NewFlagSet("get-remote", flag.ExitOnError)
uuidFlag := getRemoteFlagSet.String("uuid", "", "Client UUID")
hostGetRemoteFlag := getRemoteFlagSet.String("remote-host", "http://localhost:5000", "Address for the remote boot server")
jsonFlag := getRemoteFlagSet.Bool("json", false, "Display the result in JSON format")
enrollFlagSet := flag.NewFlagSet("enroll", flag.ExitOnError)
hostEnrollFlag := enrollFlagSet.String("remote-host", "http://localhost:5000", "Address for the remote boot server")
nameFlag := enrollFlagSet.String("name", "default", "Name for the client on the remote boot server")
2023-08-13 15:59:05 +00:00
debugFlag := flag.Bool("debug", false, "Display debug logs")
noColourFlag := flag.Bool("no-colour", false, "Disable colour logs")
2023-08-13 16:46:06 +00:00
for i, v := range os.Args {
switch v {
case "list":
args.action = actionList
case "get-remote":
args.action = actionGetRemote
case "enroll":
args.action = actionEnroll
2023-08-13 16:46:06 +00:00
default:
continue
}
firstArg = i + 1
}
2023-08-13 15:59:05 +00:00
2023-08-13 16:46:06 +00:00
switch args.action {
case actionList:
listFlagSet.Parse(os.Args[firstArg:])
case actionGetRemote:
getRemoteFlagSet.Parse(os.Args[firstArg:])
parsedID, err := uuid.Parse(*uuidFlag)
if err != nil {
return args, fmt.Errorf("invalid format for uuid %q", *uuidFlag)
}
args.id = parsedID
args.remoteAddr = *hostGetRemoteFlag
args.prettyPrint = !*jsonFlag
case actionEnroll:
enrollFlagSet.Parse(os.Args[firstArg:])
args.remoteAddr = *hostEnrollFlag
args.name = *nameFlag
2023-08-13 16:46:06 +00:00
default:
flag.Parse()
return cliArgs{}, errors.New("missing an action")
2023-08-13 15:59:05 +00:00
}
2023-08-13 16:46:06 +00:00
flag.Parse()
args.debug = *debugFlag
args.colour = !*noColourFlag
return args, nil
2023-08-13 15:59:05 +00:00
}
2023-08-13 16:46:06 +00:00
func displayAppList(l *logger.SimpleLogger) {
l.Info("Checking EFI directory for available boot images...")
apps, err := prober.GetEFIApps(l)
if err != nil {
if errors.Is(err, fs.ErrPermission) {
l.Fatal("Permission error, try to run the command as sudo")
}
l.Fatalf("Failed to check EFI directory: %s", err.Error())
}
2023-08-13 15:59:05 +00:00
l.Info("Found the following EFI applications:")
for _, a := range apps {
prefix := " "
if a.Active {
prefix = "*"
}
2023-08-19 08:54:18 +00:00
l.Infof("\t- %s[%d] %s: %s (disk id %s)", prefix, a.ID, a.Name, a.Path, a.DiskID)
2023-08-13 15:59:05 +00:00
}
}
2023-08-13 14:20:55 +00:00
func getRemoteConfig(l *logger.SimpleLogger, host string, id uuid.UUID, pretty bool) {
if pretty {
2023-08-19 08:54:18 +00:00
l.Info("Getting config from remote server...")
if err := remote.DisplayRemoteConfigPretty(context.Background(), host, id, l); err != nil {
l.Fatal(err.Error())
}
} else {
if err := remote.DisplayRemoteConfigJSON(context.Background(), host, id, l); err != nil {
l.Fatal(err.Error())
}
}
2023-08-13 16:46:06 +00:00
}
2023-08-13 14:20:55 +00:00
func enroll(l *logger.SimpleLogger, host, name string) {
l.Info("Enrolling client")
if err := remote.Enroll(context.Background(), host, name, l); err != nil {
l.Fatal(err.Error())
}
}
2023-08-13 16:46:06 +00:00
func main() {
args, err := parseArgs()
2023-08-13 15:59:05 +00:00
if err != nil {
2023-08-13 16:46:06 +00:00
l := logger.New(true, false)
l.Fatalf("Invalid command: %s", err.Error())
2023-08-13 15:59:05 +00:00
}
2023-08-13 16:46:06 +00:00
l := logger.New(args.colour, args.debug)
fmt.Print("")
2023-08-13 14:20:55 +00:00
2023-08-13 16:46:06 +00:00
switch args.action {
case actionList:
displayAppList(l)
case actionGetRemote:
getRemoteConfig(l, args.remoteAddr, args.id, args.prettyPrint)
case actionEnroll:
enroll(l, args.remoteAddr, args.name)
2023-08-13 16:46:06 +00:00
default:
l.Fatal("Unknown action")
}
2023-08-13 14:20:55 +00:00
}