2023-08-13 14:20:55 +00:00
|
|
|
package main
|
|
|
|
|
2023-08-13 15:59:05 +00:00
|
|
|
import (
|
2023-08-13 19:30:44 +00:00
|
|
|
"context"
|
2023-08-13 15:59:05 +00:00
|
|
|
"errors"
|
|
|
|
"flag"
|
2023-08-13 19:30:44 +00:00
|
|
|
"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"
|
2023-08-13 19:30:44 +00:00
|
|
|
"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
|
2023-08-13 20:34:31 +00:00
|
|
|
actionEnroll
|
2023-08-13 16:46:06 +00:00
|
|
|
actionUnknown
|
|
|
|
)
|
|
|
|
|
2023-08-13 15:59:05 +00:00
|
|
|
type cliArgs struct {
|
2023-08-13 19:30:44 +00:00
|
|
|
debug bool
|
|
|
|
colour bool
|
|
|
|
action action
|
|
|
|
id uuid.UUID
|
|
|
|
remoteAddr string
|
|
|
|
prettyPrint bool
|
2023-08-13 20:34:31 +00:00
|
|
|
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)
|
|
|
|
|
2023-08-13 19:30:44 +00:00
|
|
|
getRemoteFlagSet := flag.NewFlagSet("get-remote", flag.ExitOnError)
|
|
|
|
uuidFlag := getRemoteFlagSet.String("uuid", "", "Client UUID")
|
2023-08-13 20:34:31 +00:00
|
|
|
hostGetRemoteFlag := getRemoteFlagSet.String("remote-host", "http://localhost:5000", "Address for the remote boot server")
|
2023-08-13 19:30:44 +00:00
|
|
|
jsonFlag := getRemoteFlagSet.Bool("json", false, "Display the result in JSON format")
|
|
|
|
|
2023-08-13 20:34:31 +00:00
|
|
|
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
|
2023-08-13 20:34:31 +00:00
|
|
|
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:])
|
2023-08-13 19:30:44 +00:00
|
|
|
parsedID, err := uuid.Parse(*uuidFlag)
|
|
|
|
if err != nil {
|
|
|
|
return args, fmt.Errorf("invalid format for uuid %q", *uuidFlag)
|
|
|
|
}
|
|
|
|
args.id = parsedID
|
2023-08-13 20:34:31 +00:00
|
|
|
args.remoteAddr = *hostGetRemoteFlag
|
2023-08-13 19:30:44 +00:00
|
|
|
args.prettyPrint = !*jsonFlag
|
2023-08-13 20:34:31 +00:00
|
|
|
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
|
|
|
|
2023-08-13 19:30:44 +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...")
|
2023-08-13 19:30:44 +00:00
|
|
|
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
|
|
|
|
2023-08-13 20:34:31 +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)
|
2023-08-13 19:30:44 +00:00
|
|
|
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:
|
2023-08-13 19:30:44 +00:00
|
|
|
getRemoteConfig(l, args.remoteAddr, args.id, args.prettyPrint)
|
2023-08-13 20:34:31 +00:00
|
|
|
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
|
|
|
}
|