From 969a2899c8c06b97c5f2fdd2bca346ecd7c731f7 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Tue, 5 Sep 2023 11:59:50 +0200 Subject: [PATCH] cmd/collect: Add command to invoke inventory and BIOS configuration collection --- cmd/collect/collect.go | 19 +++++++++ cmd/collect/inventory.go | 91 ++++++++++++++++++++++++++++++++++++++++ cmd/collect/status.go | 64 ++++++++++++++++++++++++++++ main.go | 1 + 4 files changed, 175 insertions(+) create mode 100644 cmd/collect/collect.go create mode 100644 cmd/collect/inventory.go create mode 100644 cmd/collect/status.go diff --git a/cmd/collect/collect.go b/cmd/collect/collect.go new file mode 100644 index 00000000..43ecc1e7 --- /dev/null +++ b/cmd/collect/collect.go @@ -0,0 +1,19 @@ +package collect + +import ( + "github.com/metal-toolbox/mctl/cmd" + "github.com/spf13/cobra" +) + +var collect = &cobra.Command{ + Use: "collect", + Short: "Collect current server firmware status and bios configuration", + Run: func(cmd *cobra.Command, args []string) { + //nolint:errcheck // returns nil + cmd.Help() + }, +} + +func init() { + cmd.RootCmd.AddCommand(collect) +} diff --git a/cmd/collect/inventory.go b/cmd/collect/inventory.go new file mode 100644 index 00000000..b04bc402 --- /dev/null +++ b/cmd/collect/inventory.go @@ -0,0 +1,91 @@ +package collect + +import ( + "context" + "encoding/json" + "log" + + "github.com/google/uuid" + "github.com/spf13/cobra" + + "github.com/metal-toolbox/mctl/internal/app" + + coapiv1 "github.com/metal-toolbox/conditionorc/pkg/api/v1/types" + "github.com/metal-toolbox/conditionorc/pkg/types" + mctl "github.com/metal-toolbox/mctl/cmd" + rctypes "github.com/metal-toolbox/rivets/condition" +) + +type collectInventoryFlags struct { + serverID string + skipFirmwareStatusCollect bool + skipBiosConfigCollect bool +} + +var ( + flagsDefinedCollectInventory *collectInventoryFlags +) + +var collectInventoryCmd = &cobra.Command{ + Use: "inventory", + Short: "Collect current server firmware status and bios configuration", + Run: func(cmd *cobra.Command, args []string) { + collectInventory(cmd.Context()) + + }, +} + +func collectInventory(ctx context.Context) { + theApp := mctl.MustCreateApp(ctx) + + serverID, err := uuid.Parse(flagsDefinedCollectInventory.serverID) + if err != nil { + log.Fatal(err) + } + + params, err := json.Marshal(rctypes.NewInventoryTaskParameters( + serverID, + rctypes.OutofbandInventory, + !flagsDefinedCollectInventory.skipFirmwareStatusCollect, + !flagsDefinedCollectInventory.skipBiosConfigCollect, + )) + if err != nil { + log.Fatal(err) + } + + conditionCreate := coapiv1.ConditionCreate{ + Exclusive: false, + Parameters: params, + } + + client, err := app.NewConditionsClient(ctx, theApp.Config.Conditions, theApp.Reauth) + if err != nil { + log.Fatal(err) + } + + response, err := client.ServerConditionCreate(ctx, serverID, types.ConditionKind(rctypes.Inventory), conditionCreate) + if err != nil { + log.Fatal(err) + } + + condition, err := mctl.ConditionFromResponse(response) + if err != nil { + log.Fatal(err) + } + + log.Printf("status=%d msg=%s conditionID=%s", response.StatusCode, response.Message, condition.ID) + +} + +func init() { + flagsDefinedCollectInventory = &collectInventoryFlags{} + + collect.AddCommand(collectInventoryCmd) + collectInventoryCmd.PersistentFlags().StringVar(&flagsDefinedCollectInventory.serverID, "server", "", "server UUID") + collectInventoryCmd.PersistentFlags().BoolVar(&flagsDefinedCollectInventory.skipFirmwareStatusCollect, "skip-fw-status", false, "Skip firmware status data collection") + collectInventoryCmd.PersistentFlags().BoolVar(&flagsDefinedCollectInventory.skipBiosConfigCollect, "skip-bios-config", false, "Skip BIOS configuration data collection") + + if err := collectInventoryCmd.MarkPersistentFlagRequired("server"); err != nil { + log.Fatal(err) + } +} diff --git a/cmd/collect/status.go b/cmd/collect/status.go new file mode 100644 index 00000000..10c2289f --- /dev/null +++ b/cmd/collect/status.go @@ -0,0 +1,64 @@ +package collect + +import ( + "context" + "fmt" + "log" + + "github.com/google/uuid" + + "github.com/metal-toolbox/mctl/internal/app" + "github.com/spf13/cobra" + + cotypes "github.com/metal-toolbox/conditionorc/pkg/types" + mctl "github.com/metal-toolbox/mctl/cmd" + rctypes "github.com/metal-toolbox/rivets/condition" +) + +var serverIDStr string + +var inventoryStatus = &cobra.Command{ + Use: "status --server | -s ", + Short: "check the progress of a inventory collection for a server", + Run: func(cmd *cobra.Command, _ []string) { + statusCheck(cmd.Context()) + }, +} + +func statusCheck(ctx context.Context) { + theApp := mctl.MustCreateApp(ctx) + + client, err := app.NewConditionsClient(ctx, theApp.Config.Conditions, theApp.Reauth) + if err != nil { + log.Fatal(err) + } + + serverID, err := uuid.Parse(serverIDStr) + if err != nil { + log.Fatalf("parsing server id: %s", err.Error()) + } + + // cotypes to be moved into rivets library + resp, err := client.ServerConditionGet(ctx, serverID, cotypes.ConditionKind(rctypes.Inventory)) + if err != nil { + log.Fatalf("querying server conditions: %s", err.Error()) + } + + s, err := mctl.FormatConditionResponse(resp) + if err != nil { + log.Fatalf(err.Error()) + } + + fmt.Println(s) +} + +func init() { + flags := inventoryStatus.Flags() + flags.StringVarP(&serverIDStr, "server", "s", "", "server id (typically a UUID)") + + if err := inventoryStatus.MarkFlagRequired("server"); err != nil { + log.Fatalf("marking server flag as required: %s", err.Error()) + } + + collect.AddCommand(inventoryStatus) +} diff --git a/main.go b/main.go index 43296407..9034dcdb 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ package main import ( "github.com/metal-toolbox/mctl/cmd" + _ "github.com/metal-toolbox/mctl/cmd/collect" _ "github.com/metal-toolbox/mctl/cmd/create" _ "github.com/metal-toolbox/mctl/cmd/delete" _ "github.com/metal-toolbox/mctl/cmd/edit"