From 58ba020bc5585c3e214eeacb964ea1b91d46592b Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Thu, 22 Oct 2026 18:43:05 +0200 Subject: [PATCH 1/5] fsl api impl --- cmd/api/v2/commands.go | 1 + cmd/api/v2/filesystem.go | 86 ++++++++++++++++++++ cmd/completion/filesystem.go | 22 ++++++ cmd/sorters/filesystem.go | 21 +++++ cmd/tableprinters/common.go | 5 ++ cmd/tableprinters/filesystem.go | 54 +++++++++++++ go.mod | 2 +- go.sum | 4 +- pkg/helpers/machine.go | 3 +- tests/e2e/api/filesystem_test.go | 104 +++++++++++++++++++++++++ tests/e2e/testresources/filesystems.go | 70 +++++++++++++++++ 11 files changed, 367 insertions(+), 5 deletions(-) create mode 100644 cmd/api/v2/filesystem.go create mode 100644 cmd/completion/filesystem.go create mode 100644 cmd/sorters/filesystem.go create mode 100644 cmd/tableprinters/filesystem.go create mode 100644 tests/e2e/api/filesystem_test.go create mode 100644 tests/e2e/testresources/filesystems.go diff --git a/cmd/api/v2/commands.go b/cmd/api/v2/commands.go index 31dcfd0..945c1ed 100644 --- a/cmd/api/v2/commands.go +++ b/cmd/api/v2/commands.go @@ -7,6 +7,7 @@ import ( func AddCmds(cmd *cobra.Command, c *config.Config) { cmd.AddCommand(newAuditCmd(c)) + cmd.AddCommand(newFilesystemCmd(c)) cmd.AddCommand(newHealthCmd(c)) cmd.AddCommand(newImageCmd(c)) cmd.AddCommand(newIPCmd(c)) diff --git a/cmd/api/v2/filesystem.go b/cmd/api/v2/filesystem.go new file mode 100644 index 0000000..4de5032 --- /dev/null +++ b/cmd/api/v2/filesystem.go @@ -0,0 +1,86 @@ +package v2 + +import ( + "fmt" + + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/metal-stack/cli/cmd/config" + "github.com/metal-stack/cli/cmd/sorters" + "github.com/metal-stack/metal-lib/pkg/genericcli" + "github.com/metal-stack/metal-lib/pkg/genericcli/printers" + "github.com/metal-stack/metal-lib/pkg/pointer" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +type filesystem struct { + c *config.Config +} + +func newFilesystemCmd(c *config.Config) *cobra.Command { + w := &filesystem{ + c: c, + } + + cmdsConfig := &genericcli.CmdsConfig[any, any, *apiv2.FilesystemLayout]{ + BinaryName: config.BinaryName, + GenericCLI: genericcli.NewGenericCLI(w).WithFS(c.Fs), + Singular: "filesystem", + Plural: "filesystems", + Description: "a filesystem layout defines how disks, raid arrays and volumes are set up on a machine during installation", + Sorter: sorters.FilesystemSorter(), + OnlyCmds: genericcli.OnlyCmds(genericcli.ListCmd, genericcli.DescribeCmd), + DescribePrinter: func() printers.Printer { return c.DescribePrinter }, + ListPrinter: func() printers.Printer { return c.ListPrinter }, + ValidArgsFn: c.Completion.FilesystemLayout, + ListCmdMutateFn: func(cmd *cobra.Command) { + cmd.Flags().String("id", "", "id of the filesystem layout which should be listed") + }, + } + + return genericcli.NewCmds(cmdsConfig) +} + +func (c *filesystem) Get(id string) (*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Apiv2().Filesystem().Get(ctx, &apiv2.FilesystemServiceGetRequest{ + Id: id, + }) + if err != nil { + return nil, fmt.Errorf("failed to get filesystem layout: %w", err) + } + + return resp.FilesystemLayout, nil +} + +func (c *filesystem) List() ([]*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Apiv2().Filesystem().List(ctx, &apiv2.FilesystemServiceListRequest{ + Id: pointer.PointerOrNil(viper.GetString("id")), + }) + if err != nil { + return nil, fmt.Errorf("failed to list filesystem layouts: %w", err) + } + + return resp.FilesystemLayouts, nil +} + +func (c *filesystem) Create(rq any) (*apiv2.FilesystemLayout, error) { + panic("unimplemented") +} + +func (c *filesystem) Delete(id string) (*apiv2.FilesystemLayout, error) { + panic("unimplemented") +} + +func (c *filesystem) Convert(r *apiv2.FilesystemLayout) (string, any, any, error) { + panic("unimplemented") +} + +func (c *filesystem) Update(rq any) (*apiv2.FilesystemLayout, error) { + panic("unimplemented") +} diff --git a/cmd/completion/filesystem.go b/cmd/completion/filesystem.go new file mode 100644 index 0000000..358c9dc --- /dev/null +++ b/cmd/completion/filesystem.go @@ -0,0 +1,22 @@ +package completion + +import ( + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/metal-stack/metal-lib/pkg/pointer" + "github.com/spf13/cobra" +) + +func (c *Completion) FilesystemLayout(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + resp, err := c.Client.Apiv2().Filesystem().List(cmd.Context(), &apiv2.FilesystemServiceListRequest{}) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var names []string + + for _, fsl := range resp.FilesystemLayouts { + names = append(names, fsl.Id+"\t"+pointer.SafeDeref(fsl.Name)) + } + + return names, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cmd/sorters/filesystem.go b/cmd/sorters/filesystem.go new file mode 100644 index 0000000..a5c4ff9 --- /dev/null +++ b/cmd/sorters/filesystem.go @@ -0,0 +1,21 @@ +package sorters + +import ( + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/metal-stack/metal-lib/pkg/multisort" + "github.com/metal-stack/metal-lib/pkg/pointer" +) + +func FilesystemSorter() *multisort.Sorter[*apiv2.FilesystemLayout] { + return multisort.New(multisort.FieldMap[*apiv2.FilesystemLayout]{ + "id": func(a, b *apiv2.FilesystemLayout, descending bool) multisort.CompareResult { + return multisort.Compare(a.Id, b.Id, descending) + }, + "name": func(a, b *apiv2.FilesystemLayout, descending bool) multisort.CompareResult { + return multisort.Compare(pointer.SafeDeref(a.Name), pointer.SafeDeref(b.Name), descending) + }, + "description": func(a, b *apiv2.FilesystemLayout, descending bool) multisort.CompareResult { + return multisort.Compare(pointer.SafeDeref(a.Description), pointer.SafeDeref(b.Description), descending) + }, + }, multisort.Keys{{ID: "id"}, {ID: "name"}}) +} diff --git a/cmd/tableprinters/common.go b/cmd/tableprinters/common.go index f7c820f..a349c4a 100644 --- a/cmd/tableprinters/common.go +++ b/cmd/tableprinters/common.go @@ -56,6 +56,11 @@ func (t *TablePrinter) ToHeaderAndRows(data any, wide bool) ([]string, [][]strin case []*apiv2.Component: return t.ComponentTable(d, wide) + case *apiv2.FilesystemLayout: + return t.FilesystemTable(pointer.WrapInSlice(d), wide) + case []*apiv2.FilesystemLayout: + return t.FilesystemTable(d, wide) + case *apiv2.Network: return t.NetworkTable(pointer.WrapInSlice(d), wide) case []*apiv2.Network: diff --git a/cmd/tableprinters/filesystem.go b/cmd/tableprinters/filesystem.go new file mode 100644 index 0000000..3328446 --- /dev/null +++ b/cmd/tableprinters/filesystem.go @@ -0,0 +1,54 @@ +package tableprinters + +import ( + "fmt" + "sort" + "strconv" + "strings" + + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/metal-stack/metal-lib/pkg/pointer" +) + +func (t *TablePrinter) FilesystemTable(data []*apiv2.FilesystemLayout, wide bool) ([]string, [][]string, error) { + var ( + header = []string{"ID", "Name", "Description", "Sizes", "Images"} + rows [][]string + ) + + if wide { + header = append(header, "Filesystems", "Disks", "Raid", "Volume Groups", "Logical Volumes") + } + + for _, fsl := range data { + row := []string{fsl.Id, pointer.SafeDeref(fsl.Name), pointer.SafeDeref(fsl.Description)} + + var ( + sizes []string + images []string + ) + if fsl.Constraints != nil { + sizes = fsl.Constraints.Sizes + for k, v := range fsl.Constraints.Images { + images = append(images, fmt.Sprintf("%s:%s", k, v)) + } + sort.Strings(images) + } + + row = append(row, strings.Join(sizes, ","), strings.Join(images, ",")) + + if wide { + row = append(row, + strconv.Itoa(len(fsl.Filesystems)), + strconv.Itoa(len(fsl.Disks)), + strconv.Itoa(len(fsl.Raid)), + strconv.Itoa(len(fsl.VolumeGroups)), + strconv.Itoa(len(fsl.LogicalVolumes)), + ) + } + + rows = append(rows, row) + } + + return header, rows, nil +} diff --git a/go.mod b/go.mod index cf0dfe8..3beefa4 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/google/uuid v1.6.0 github.com/metal-stack/api v0.8.0 github.com/metal-stack/metal-console v0.8.2 - github.com/metal-stack/metal-lib v0.26.3 + github.com/metal-stack/metal-lib v0.26.4 github.com/metal-stack/v v1.0.3 github.com/spf13/afero v1.15.0 github.com/spf13/cobra v1.10.2 diff --git a/go.sum b/go.sum index 2aa4f99..af07d3e 100644 --- a/go.sum +++ b/go.sum @@ -195,8 +195,8 @@ github.com/metal-stack/api v0.8.0 h1:olAQtHx7uv3f/jaKKo7aVILhZgO5McQTLeKfS0FkolM github.com/metal-stack/api v0.8.0/go.mod h1:rWdj0dTAg2w/WuQhIZ+JVp9b68v6VVCm1k7sLx4U+PQ= github.com/metal-stack/metal-console v0.8.2 h1:Y86penzEROJKcLica1PeE2ddtr9G0/u16HiCAYXaxxU= github.com/metal-stack/metal-console v0.8.2/go.mod h1:ZkselOaxF/iELFL9Tku3maXgpX4DM0CHjoG7CGuky6E= -github.com/metal-stack/metal-lib v0.26.3 h1:K5gLoD65m6p3l6qCPrfavIdvNdWfmF2QdXrvU2URaZs= -github.com/metal-stack/metal-lib v0.26.3/go.mod h1:cNXjPBs8SFnjqfBobuSbm5mDk6E/jS8PVeIOrV/7POE= +github.com/metal-stack/metal-lib v0.26.4 h1:Qg+JorX0AgQCkrCK07wvstGEoRcm/Y97E2UG5ZBAXjo= +github.com/metal-stack/metal-lib v0.26.4/go.mod h1:cNXjPBs8SFnjqfBobuSbm5mDk6E/jS8PVeIOrV/7POE= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= diff --git a/pkg/helpers/machine.go b/pkg/helpers/machine.go index b2836e2..1d13ce3 100644 --- a/pkg/helpers/machine.go +++ b/pkg/helpers/machine.go @@ -575,6 +575,5 @@ IPs can be added per network colon separated, these ips must be already allocate genericcli.Must(cmd.RegisterFlagCompletionFunc("size", completion.Size)) genericcli.Must(cmd.RegisterFlagCompletionFunc("project", completion.Project)) genericcli.Must(cmd.RegisterFlagCompletionFunc("image", completion.Image)) - // FIXME implement - // genericcli.Must(cmd.RegisterFlagCompletionFunc("filesystem-layout", c.c.Completion.FilesystemLayoutListCompletion)) + genericcli.Must(cmd.RegisterFlagCompletionFunc("filesystem-layout", completion.FilesystemLayout)) } diff --git a/tests/e2e/api/filesystem_test.go b/tests/e2e/api/filesystem_test.go new file mode 100644 index 0000000..e9a447c --- /dev/null +++ b/tests/e2e/api/filesystem_test.go @@ -0,0 +1,104 @@ +package api_e2e + +import ( + "testing" + + "connectrpc.com/connect" + "github.com/metal-stack/api/go/client" + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + e2erootcmd "github.com/metal-stack/cli/testing/e2e" + "github.com/metal-stack/cli/tests/e2e/testresources" + "github.com/metal-stack/metal-lib/pkg/genericcli/e2e" +) + +func Test_FileSystemCmd_List(t *testing.T) { + tests := []*e2e.Test[apiv2.FilesystemServiceListResponse, *apiv2.FilesystemLayout]{ + { + Name: "list", + CmdArgs: []string{"filesystem", "list"}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &apiv2.FilesystemServiceListRequest{}, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&apiv2.FilesystemServiceListResponse{ + FilesystemLayouts: []*apiv2.FilesystemLayout{ + testresources.FilesystemLayout1(), + testresources.FilesystemLayout2(), + }, + }) + }, + }, + }, + }), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + ubuntu-raid1 Ubuntu Raid1 Raid1 layout for ubuntu machines m2.large ubuntu:>= 24.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + ubuntu-raid1 Ubuntu Raid1 Raid1 layout for ubuntu machines m2.large ubuntu:>= 24.0 0 0 1 1 1 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +ubuntu-raid1 Ubuntu Raid1 +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + | ubuntu-raid1 | Ubuntu Raid1 | Raid1 layout for ubuntu machines | m2.large | ubuntu:>= 24.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_FileSystemCmd_Describe(t *testing.T) { + tests := []*e2e.Test[apiv2.FilesystemServiceGetResponse, *apiv2.FilesystemLayout]{ + { + Name: "describe", + CmdArgs: []string{"filesystem", "describe", testresources.FilesystemLayout1().Id}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &apiv2.FilesystemServiceGetRequest{ + Id: testresources.FilesystemLayout1().Id, + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&apiv2.FilesystemServiceGetResponse{ + FilesystemLayout: testresources.FilesystemLayout1(), + }) + }, + }, + }, + }), + WantProtoObject: testresources.FilesystemLayout1(), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} diff --git a/tests/e2e/testresources/filesystems.go b/tests/e2e/testresources/filesystems.go new file mode 100644 index 0000000..b525cd0 --- /dev/null +++ b/tests/e2e/testresources/filesystems.go @@ -0,0 +1,70 @@ +package testresources + +import apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + +var ( + FilesystemLayout1 = func() *apiv2.FilesystemLayout { + return &apiv2.FilesystemLayout{ + Id: "debian-default", + Name: new("Debian Default"), + Description: new("Default layout for debian machines"), + Meta: &apiv2.Meta{}, + Filesystems: []*apiv2.Filesystem{ + { + Device: "/dev/sda1", + Format: apiv2.Format_FORMAT_EXT4, + Path: new("/"), + }, + }, + Disks: []*apiv2.Disk{ + { + Device: "/dev/sda", + Partitions: []*apiv2.DiskPartition{ + { + Number: 1, + Size: 1024, + GptType: new(apiv2.GPTType_GPT_TYPE_LINUX), + }, + }, + }, + }, + Constraints: &apiv2.FilesystemLayoutConstraints{ + Sizes: []string{"m2.small"}, + Images: map[string]string{"debian": ">= 12.0"}, + }, + } + } + FilesystemLayout2 = func() *apiv2.FilesystemLayout { + return &apiv2.FilesystemLayout{ + Id: "ubuntu-raid1", + Name: new("Ubuntu Raid1"), + Description: new("Raid1 layout for ubuntu machines"), + Meta: &apiv2.Meta{}, + Raid: []*apiv2.Raid{ + { + ArrayName: "md0", + Devices: []string{"/dev/sda", "/dev/sdb"}, + Level: apiv2.RaidLevel_RAID_LEVEL_1, + }, + }, + VolumeGroups: []*apiv2.VolumeGroup{ + { + Name: "vg0", + Devices: []string{"/dev/md0"}, + }, + }, + LogicalVolumes: []*apiv2.LogicalVolume{ + { + Name: "lv-root", + VolumeGroup: "vg0", + Size: 2048, + LvmType: apiv2.LVMType_LVM_TYPE_LINEAR, + }, + }, + Constraints: &apiv2.FilesystemLayoutConstraints{ + Sizes: []string{"m2.large"}, + Images: map[string]string{"ubuntu": ">= 24.0"}, + }, + } + } +) From 9e653b3a40b9876964d0f340f6c5d2a8f123f980 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Thu, 22 Oct 2026 20:12:57 +0200 Subject: [PATCH 2/5] fsl admin impl --- cmd/admin/v2/commands.go | 1 + cmd/admin/v2/filesystem.go | 196 +++++++++++++++ tests/e2e/admin/filesystem_test.go | 375 +++++++++++++++++++++++++++++ 3 files changed, 572 insertions(+) create mode 100644 cmd/admin/v2/filesystem.go create mode 100644 tests/e2e/admin/filesystem_test.go diff --git a/cmd/admin/v2/commands.go b/cmd/admin/v2/commands.go index 6bd3dec..5960e76 100644 --- a/cmd/admin/v2/commands.go +++ b/cmd/admin/v2/commands.go @@ -16,6 +16,7 @@ func AddCmds(cmd *cobra.Command, c *config.Config) { adminCmd.AddCommand(newAuditCmd(c)) adminCmd.AddCommand(newComponentCmd(c)) + adminCmd.AddCommand(newFilesystemCmd(c)) adminCmd.AddCommand(newImageCmd(c)) adminCmd.AddCommand(newIPCmd(c)) adminCmd.AddCommand(newMachineCmd(c)) diff --git a/cmd/admin/v2/filesystem.go b/cmd/admin/v2/filesystem.go new file mode 100644 index 0000000..da5d57d --- /dev/null +++ b/cmd/admin/v2/filesystem.go @@ -0,0 +1,196 @@ +package v2 + +import ( + "fmt" + + "github.com/metal-stack/api/go/errorutil" + adminv2 "github.com/metal-stack/api/go/metalstack/admin/v2" + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/metal-stack/cli/cmd/config" + "github.com/metal-stack/cli/cmd/sorters" + "github.com/metal-stack/cli/pkg/helpers" + "github.com/metal-stack/metal-lib/pkg/genericcli" + "github.com/metal-stack/metal-lib/pkg/genericcli/printers" + "github.com/metal-stack/metal-lib/pkg/pointer" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +type filesystem struct { + c *config.Config +} + +func newFilesystemCmd(c *config.Config) *cobra.Command { + w := &filesystem{ + c: c, + } + + cmdsConfig := &genericcli.CmdsConfig[*adminv2.FilesystemServiceCreateRequest, *adminv2.FilesystemServiceUpdateRequest, *apiv2.FilesystemLayout]{ + BinaryName: config.BinaryName, + GenericCLI: genericcli.NewGenericCLI(w).WithFS(c.Fs), + Singular: "filesystem", + Plural: "filesystems", + Description: "manage filesystem layouts which define how disks, raid arrays and volumes are set up on machines during installation", + Sorter: sorters.FilesystemSorter(), + DescribePrinter: func() printers.Printer { return c.DescribePrinter }, + ListPrinter: func() printers.Printer { return c.ListPrinter }, + ValidArgsFn: c.Completion.FilesystemLayout, + ListCmdMutateFn: func(cmd *cobra.Command) { + cmd.Flags().String("id", "", "id of the filesystem layout to filter for") + }, + } + + matchCmd := &cobra.Command{ + Use: "match", + Short: "matches a filesystem layout to a size and image or to a machine", + Long: `matches a filesystem layout either to a given size and image combination, +or checks whether a given filesystem layout matches a given machine.`, + RunE: func(cmd *cobra.Command, _ []string) error { + return w.match(cmd) + }, + } + matchCmd.Flags().String("size", "", "machine size to match against a filesystem layout") + matchCmd.Flags().String("image", "", "machine image to match against a filesystem layout") + matchCmd.Flags().String("machine", "", "uuid of the machine to check against a filesystem layout") + matchCmd.Flags().String("filesystem-layout", "", "id of the filesystem layout to check against a machine") + + genericcli.Must(matchCmd.RegisterFlagCompletionFunc("size", c.Completion.Size)) + genericcli.Must(matchCmd.RegisterFlagCompletionFunc("image", c.Completion.Image)) + genericcli.Must(matchCmd.RegisterFlagCompletionFunc("machine", c.Completion.Machine)) + genericcli.Must(matchCmd.RegisterFlagCompletionFunc("filesystem-layout", c.Completion.FilesystemLayout)) + + return genericcli.NewCmds(cmdsConfig, matchCmd) +} + +func (c *filesystem) Get(id string) (*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Apiv2().Filesystem().Get(ctx, &apiv2.FilesystemServiceGetRequest{ + Id: id, + }) + if err != nil { + return nil, fmt.Errorf("failed to get filesystem layout: %w", err) + } + + return resp.FilesystemLayout, nil +} + +func (c *filesystem) List() ([]*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Apiv2().Filesystem().List(ctx, &apiv2.FilesystemServiceListRequest{ + Id: pointer.PointerOrNil(viper.GetString("id")), + }) + if err != nil { + return nil, fmt.Errorf("failed to list filesystem layouts: %w", err) + } + + return resp.FilesystemLayouts, nil +} + +func (c *filesystem) Create(rq *adminv2.FilesystemServiceCreateRequest) (*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Adminv2().Filesystem().Create(ctx, rq) + if err != nil { + if errorutil.IsConflict(err) { + return nil, genericcli.AlreadyExistsError() + } + + return nil, fmt.Errorf("failed to create filesystem layout: %w", err) + } + + return resp.FilesystemLayout, nil +} + +func (c *filesystem) Update(rq *adminv2.FilesystemServiceUpdateRequest) (*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Adminv2().Filesystem().Update(ctx, rq) + if err != nil { + return nil, fmt.Errorf("failed to update filesystem layout: %w", err) + } + + return resp.FilesystemLayout, nil +} + +func (c *filesystem) Delete(id string) (*apiv2.FilesystemLayout, error) { + ctx, cancel := c.c.NewRequestContext() + defer cancel() + + resp, err := c.c.Client.Adminv2().Filesystem().Delete(ctx, &adminv2.FilesystemServiceDeleteRequest{ + Id: id, + }) + if err != nil { + return nil, fmt.Errorf("failed to delete filesystem layout: %w", err) + } + + return resp.FilesystemLayout, nil +} + +func (c *filesystem) Convert(r *apiv2.FilesystemLayout) (string, *adminv2.FilesystemServiceCreateRequest, *adminv2.FilesystemServiceUpdateRequest, error) { + return r.Id, + &adminv2.FilesystemServiceCreateRequest{ + FilesystemLayout: r, + }, + &adminv2.FilesystemServiceUpdateRequest{ + Id: r.Id, + UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), + Name: r.Name, + Description: r.Description, + Filesystems: r.Filesystems, + Disks: r.Disks, + Raid: r.Raid, + VolumeGroups: r.VolumeGroups, + LogicalVolumes: r.LogicalVolumes, + Constraints: r.Constraints, + }, + nil +} + +func (w *filesystem) match(_ *cobra.Command) error { + var ( + sizeSet = viper.IsSet("size") + imageSet = viper.IsSet("image") + machineSet = viper.IsSet("machine") + layoutSet = viper.IsSet("filesystem-layout") + req *adminv2.FilesystemServiceMatchRequest + ) + + switch { + case sizeSet && imageSet: + req = &adminv2.FilesystemServiceMatchRequest{ + Match: &adminv2.FilesystemServiceMatchRequest_SizeAndImage{ + SizeAndImage: &adminv2.MatchImageAndSize{ + Size: viper.GetString("size"), + Image: viper.GetString("image"), + }, + }, + } + case machineSet && layoutSet: + req = &adminv2.FilesystemServiceMatchRequest{ + Match: &adminv2.FilesystemServiceMatchRequest_MachineAndFilesystemlayout{ + MachineAndFilesystemlayout: &adminv2.MatchMachineAndFilesystemLayout{ + Machine: viper.GetString("machine"), + FilesystemLayout: viper.GetString("filesystem-layout"), + }, + }, + } + default: + return fmt.Errorf("either both --size and --image or both --machine and --filesystem-layout must be set") + } + + ctx, cancel := w.c.NewRequestContext() + defer cancel() + + resp, err := w.c.Client.Adminv2().Filesystem().Match(ctx, req) + if err != nil { + return fmt.Errorf("failed to match filesystem layout: %w", err) + } + + return w.c.ListPrinter.Print(resp.FilesystemLayout) +} diff --git a/tests/e2e/admin/filesystem_test.go b/tests/e2e/admin/filesystem_test.go new file mode 100644 index 0000000..89790b2 --- /dev/null +++ b/tests/e2e/admin/filesystem_test.go @@ -0,0 +1,375 @@ +package admin_e2e + +import ( + "fmt" + "testing" + + "connectrpc.com/connect" + "github.com/metal-stack/api/go/client" + adminv2 "github.com/metal-stack/api/go/metalstack/admin/v2" + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + e2erootcmd "github.com/metal-stack/cli/testing/e2e" + "github.com/metal-stack/cli/tests/e2e/testresources" + e2e "github.com/metal-stack/metal-lib/pkg/genericcli/e2e" + "github.com/spf13/afero" + "github.com/stretchr/testify/require" +) + +func Test_AdminFileSystemCmd_List(t *testing.T) { + tests := []*e2e.Test[apiv2.FilesystemServiceListResponse, *apiv2.FilesystemLayout]{ + { + Name: "list", + CmdArgs: []string{"admin", "filesystem", "list"}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &apiv2.FilesystemServiceListRequest{}, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&apiv2.FilesystemServiceListResponse{ + FilesystemLayouts: []*apiv2.FilesystemLayout{ + testresources.FilesystemLayout1(), + testresources.FilesystemLayout2(), + }, + }) + }, + }, + }, + }), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + ubuntu-raid1 Ubuntu Raid1 Raid1 layout for ubuntu machines m2.large ubuntu:>= 24.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + ubuntu-raid1 Ubuntu Raid1 Raid1 layout for ubuntu machines m2.large ubuntu:>= 24.0 0 0 1 1 1 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +ubuntu-raid1 Ubuntu Raid1 +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + | ubuntu-raid1 | Ubuntu Raid1 | Raid1 layout for ubuntu machines | m2.large | ubuntu:>= 24.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Describe(t *testing.T) { + tests := []*e2e.Test[apiv2.FilesystemServiceGetResponse, *apiv2.FilesystemLayout]{ + { + Name: "describe", + CmdArgs: []string{"admin", "filesystem", "describe", testresources.FilesystemLayout1().Id}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &apiv2.FilesystemServiceGetRequest{ + Id: testresources.FilesystemLayout1().Id, + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&apiv2.FilesystemServiceGetResponse{ + FilesystemLayout: testresources.FilesystemLayout1(), + }) + }, + }, + }, + }), + WantProtoObject: testresources.FilesystemLayout1(), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Create(t *testing.T) { + tests := []*e2e.Test[adminv2.FilesystemServiceCreateResponse, *apiv2.FilesystemLayout]{ + { + Name: "create from file", + CmdArgs: append([]string{"admin", "filesystem", "create"}, e2e.AppendFromFileCommonArgs()...), + NewRootCmd: e2erootcmd.NewRootCmd(t, + &e2erootcmd.TestConfig{ + FsMocks: func(fs *afero.Afero) { + require.NoError(t, fs.WriteFile(e2e.InputFilePath, e2e.MustMarshal(t, testresources.FilesystemLayout1()), 0755)) + }, + ClientCalls: []client.ClientCall{ + { + WantRequest: &adminv2.FilesystemServiceCreateRequest{ + FilesystemLayout: testresources.FilesystemLayout1(), + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&adminv2.FilesystemServiceCreateResponse{ + FilesystemLayout: testresources.FilesystemLayout1(), + }) + }, + }, + }, + }), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Update(t *testing.T) { + layout := testresources.FilesystemLayout1() + + tests := []*e2e.Test[adminv2.FilesystemServiceUpdateResponse, *apiv2.FilesystemLayout]{ + { + Name: "update from file", + CmdArgs: append([]string{"admin", "filesystem", "update"}, e2e.AppendFromFileCommonArgs()...), + NewRootCmd: e2erootcmd.NewRootCmd(t, + &e2erootcmd.TestConfig{ + FsMocks: func(fs *afero.Afero) { + require.NoError(t, fs.WriteFile(e2e.InputFilePath, e2e.MustMarshal(t, layout), 0755)) + }, + ClientCalls: []client.ClientCall{ + { + WantRequest: &adminv2.FilesystemServiceUpdateRequest{ + Id: layout.Id, + UpdateMeta: &apiv2.UpdateMeta{LockingStrategy: apiv2.OptimisticLockingStrategy_OPTIMISTIC_LOCKING_STRATEGY_SERVER}, + Name: layout.Name, + Description: layout.Description, + Filesystems: layout.Filesystems, + Disks: layout.Disks, + Raid: layout.Raid, + VolumeGroups: layout.VolumeGroups, + LogicalVolumes: layout.LogicalVolumes, + Constraints: layout.Constraints, + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&adminv2.FilesystemServiceUpdateResponse{ + FilesystemLayout: layout, + }) + }, + }, + }, + }), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Delete(t *testing.T) { + tests := []*e2e.Test[adminv2.FilesystemServiceDeleteResponse, *apiv2.FilesystemLayout]{ + { + Name: "delete", + CmdArgs: []string{"admin", "filesystem", "delete", testresources.FilesystemLayout1().Id}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &adminv2.FilesystemServiceDeleteRequest{ + Id: testresources.FilesystemLayout1().Id, + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&adminv2.FilesystemServiceDeleteResponse{ + FilesystemLayout: testresources.FilesystemLayout1(), + }) + }, + }, + }, + }), + WantProtoObject: testresources.FilesystemLayout1(), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Match_SizeAndImage(t *testing.T) { + tests := []*e2e.Test[adminv2.FilesystemServiceMatchResponse, *apiv2.FilesystemLayout]{ + { + Name: "match size and image", + CmdArgs: []string{"admin", "filesystem", "match", "--size", "m2.small", "--image", "debian"}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &adminv2.FilesystemServiceMatchRequest{ + Match: &adminv2.FilesystemServiceMatchRequest_SizeAndImage{ + SizeAndImage: &adminv2.MatchImageAndSize{ + Size: "m2.small", + Image: "debian", + }, + }, + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&adminv2.FilesystemServiceMatchResponse{ + FilesystemLayout: testresources.FilesystemLayout1(), + }) + }, + }, + }, + }), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Match_MachineAndLayout(t *testing.T) { + machineUUID := "12345678-1234-1234-1234-123456789abc" + + tests := []*e2e.Test[adminv2.FilesystemServiceMatchResponse, *apiv2.FilesystemLayout]{ + { + Name: "match machine and filesystem layout", + CmdArgs: []string{"admin", "filesystem", "match", "--machine", machineUUID, "--filesystem-layout", testresources.FilesystemLayout1().Id}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ + ClientCalls: []client.ClientCall{ + { + WantRequest: &adminv2.FilesystemServiceMatchRequest{ + Match: &adminv2.FilesystemServiceMatchRequest_MachineAndFilesystemlayout{ + MachineAndFilesystemlayout: &adminv2.MatchMachineAndFilesystemLayout{ + Machine: machineUUID, + FilesystemLayout: testresources.FilesystemLayout1().Id, + }, + }, + }, + WantResponse: func() connect.AnyResponse { + return connect.NewResponse(&adminv2.FilesystemServiceMatchResponse{ + FilesystemLayout: testresources.FilesystemLayout1(), + }) + }, + }, + }, + }), + WantTable: new(` + ID NAME DESCRIPTION SIZES IMAGES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 + `), + WantWideTable: new(` + ID NAME DESCRIPTION SIZES IMAGES FILESYSTEMS DISKS RAID VOLUME GROUPS LOGICAL VOLUMES + debian-default Debian Default Default layout for debian machines m2.small debian:>= 12.0 1 1 0 0 0 + `), + Template: new("{{ .id }} {{ .name }}"), + WantTemplate: new(` +debian-default Debian Default +`), + WantMarkdown: new(` + | ID | NAME | DESCRIPTION | SIZES | IMAGES | + |----------------|----------------|------------------------------------|----------|----------------| + | debian-default | Debian Default | Default layout for debian machines | m2.small | debian:>= 12.0 | + `), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} + +func Test_AdminFileSystemCmd_Match_InvalidFlags(t *testing.T) { + tests := []*e2e.Test[any, any]{ + { + Name: "match without flags fails", + CmdArgs: []string{"admin", "filesystem", "match"}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{}), + WantErr: fmt.Errorf("either both --size and --image or both --machine and --filesystem-layout must be set"), + }, + { + Name: "match with only size fails", + CmdArgs: []string{"admin", "filesystem", "match", "--size", "m2.small"}, + NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{}), + WantErr: fmt.Errorf("either both --size and --image or both --machine and --filesystem-layout must be set"), + }, + } + for _, tt := range tests { + tt.TestCmd(t) + } +} From b5ffaf1825b9d6d631aacff021b213989063b12c Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Thu, 22 Oct 2026 20:27:28 +0200 Subject: [PATCH 3/5] Update go modules --- docs/admin/metalctlv2_admin.md | 1 + docs/admin/metalctlv2_admin_machine_create.md | 79 ++--- docs/metalctlv2.md | 1 + docs/metalctlv2_machine_create.md | 77 ++-- go.mod | 77 ++-- go.sum | 329 +++++++++--------- 6 files changed, 288 insertions(+), 276 deletions(-) diff --git a/docs/admin/metalctlv2_admin.md b/docs/admin/metalctlv2_admin.md index d32ad0b..f6b5a8e 100644 --- a/docs/admin/metalctlv2_admin.md +++ b/docs/admin/metalctlv2_admin.md @@ -30,6 +30,7 @@ these commands utilize the admin api, which can only be accessed by metal-stack * [metalctlv2](metalctlv2.md) - cli for managing entities in metal-stack * [metalctlv2 admin audit](metalctlv2_admin_audit.md) - manage audit entities * [metalctlv2 admin component](metalctlv2_admin_component.md) - manage component entities +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities * [metalctlv2 admin image](metalctlv2_admin_image.md) - manage image entities * [metalctlv2 admin ip](metalctlv2_admin_ip.md) - manage ip entities * [metalctlv2 admin machine](metalctlv2_admin_machine.md) - manage machine entities diff --git a/docs/admin/metalctlv2_admin_machine_create.md b/docs/admin/metalctlv2_admin_machine_create.md index 2076e74..6fc1dc6 100644 --- a/docs/admin/metalctlv2_admin_machine_create.md +++ b/docs/admin/metalctlv2_admin_machine_create.md @@ -49,45 +49,46 @@ Once created the machine installation can not be modified anymore. ### Options ``` - --allocation-type string allocation type, can be either machine|firewall (default "machine") - --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. - --description string Description of the machine to create. [optional] - --dns-servers strings dns servers to add to the machine or firewall. [optional] - -f, --file string filename of the create or update request in yaml format, or - for stdin. - - Example: - $ metalctlv2 machine describe machine-1 -o yaml > machine.yaml - $ vi machine.yaml - $ # either via stdin - $ cat machine.yaml | metalctlv2 machine create -f - - $ # or via file - $ metalctlv2 machine create -f machine.yaml - - the file can also contain multiple documents and perform a bulk operation. - - --filesystem-layout string Filesystemlayout to use during machine installation. [optional] - -h, --help help for create - --hostname string Hostname of the machine. [required] - --id string id of the machine to create. [optional] - --image string OS Image to install. [required] - --labels strings labels to add to the machine, use it like: --labels "a=b" or --labels "a=". - --name string Name of the machine. [optional] - --networks strings Adds a network. Usage: [--networks NETWORK[:ip[;ip]][,NETWORK[:ip[;ip]]... - NETWORK specifies the name or id of an existing network. - IPs can be added per network colon separated, these ips must be already allocated upfront. If no ip(s) are specified per network, one ip per network is allocated. - - --ntp-servers strings ntp servers to add to the machine or firewall. [optional] - --partition string partition/datacenter where the machine is created. [required, except for reserved machines] - --placement-labels strings placement tags used for rack spreading - -p, --project string Project where the machine should belong to. [required] - --size string Size of the machine. [required, except for reserved machines] - --skip-security-prompts skips security prompt for bulk operations - -i, --ssh-public-key string SSH public key for access via ssh and console. [optional] - Can be either the public key as string, or pointing to the public key file to use e.g.: "@~/.ssh/id_rsa.pub". - If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order. - --timestamps when used with --file (bulk operation): prints timestamps in-between the operations - --userdata string cloud-init.io compatible userdata. [optional] - Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg". + --allocation-type string allocation type, can be either machine|firewall (default "machine") + --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. + --description string Description of the machine to create. [optional] + --dns-servers strings dns servers to add to the machine or firewall. [optional] + -f, --file string filename of the create or update request in yaml format, or - for stdin. + + Example: + $ metalctlv2 machine describe machine-1 -o yaml > machine.yaml + $ vi machine.yaml + $ # either via stdin + $ cat machine.yaml | metalctlv2 machine create -f - + $ # or via file + $ metalctlv2 machine create -f machine.yaml + + the file can also contain multiple documents and perform a bulk operation. + + --filesystem-layout string Filesystemlayout to use during machine installation. [optional] + -h, --help help for create + --hostname string Hostname of the machine. [required] + --id string id of the machine to create. [optional] + --image string OS Image to install. [required] + --labels strings labels to add to the machine, use it like: --labels "a=b" or --labels "a=". + --name string Name of the machine. [optional] + --networks strings Adds a network. Usage: [--networks NETWORK[:ip[;ip]][,NETWORK[:ip[;ip]]... + NETWORK specifies the name or id of an existing network. + IPs can be added per network colon separated, these ips must be already allocated upfront. If no ip(s) are specified per network, one ip per network is allocated. + + --ntp-servers strings ntp servers to add to the machine or firewall. [optional] + --partition string partition/datacenter where the machine is created. [required, except for reserved machines] + --placement-labels strings placement tags used for rack spreading + -p, --project string Project where the machine should belong to. [required] + --size string Size of the machine. [required, except for reserved machines] + --skip-security-prompts skips security prompt for bulk operations + -i, --ssh-public-key stringArray SSH public key for access via ssh and console. [optional] + Multiple keys can be passed by doing -i [key] -i [key] ... + Can be either the public keys as strings, or pointing to the public keys file to use e.g.: "@~/.ssh/id_rsa.pub". + If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order. + --timestamps when used with --file (bulk operation): prints timestamps in-between the operations + --userdata string cloud-init.io compatible userdata. [optional] + Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg". ``` ### Options inherited from parent commands diff --git a/docs/metalctlv2.md b/docs/metalctlv2.md index a4524aa..d13d48c 100644 --- a/docs/metalctlv2.md +++ b/docs/metalctlv2.md @@ -22,6 +22,7 @@ cli for managing entities in metal-stack * [metalctlv2 audit](metalctlv2_audit.md) - manage audit entities * [metalctlv2 completion](metalctlv2_completion.md) - Generate the autocompletion script for the specified shell * [metalctlv2 context](metalctlv2_context.md) - manage cli contexts +* [metalctlv2 filesystem](metalctlv2_filesystem.md) - manage filesystem entities * [metalctlv2 health](metalctlv2_health.md) - print the client and server health information * [metalctlv2 image](metalctlv2_image.md) - manage image entities * [metalctlv2 ip](metalctlv2_ip.md) - manage ip entities diff --git a/docs/metalctlv2_machine_create.md b/docs/metalctlv2_machine_create.md index 325fcf1..d1f474a 100644 --- a/docs/metalctlv2_machine_create.md +++ b/docs/metalctlv2_machine_create.md @@ -9,44 +9,45 @@ metalctlv2 machine create [flags] ### Options ``` - --allocation-type string allocation type, can be either machine|firewall (default "machine") - --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. - --description string Description of the machine to create. [optional] - --dns-servers strings dns servers to add to the machine or firewall. [optional] - -f, --file string filename of the create or update request in yaml format, or - for stdin. - - Example: - $ metalctlv2 machine describe machine-1 -o yaml > machine.yaml - $ vi machine.yaml - $ # either via stdin - $ cat machine.yaml | metalctlv2 machine create -f - - $ # or via file - $ metalctlv2 machine create -f machine.yaml - - the file can also contain multiple documents and perform a bulk operation. - - --filesystem-layout string Filesystemlayout to use during machine installation. [optional] - -h, --help help for create - --hostname string Hostname of the machine. [required] - --image string OS Image to install. [required] - --labels strings labels to add to the machine, use it like: --labels "a=b" or --labels "a=". - --name string Name of the machine. [optional] - --networks strings Adds a network. Usage: [--networks NETWORK[:ip[;ip]][,NETWORK[:ip[;ip]]... - NETWORK specifies the name or id of an existing network. - IPs can be added per network colon separated, these ips must be already allocated upfront. If no ip(s) are specified per network, one ip per network is allocated. - - --ntp-servers strings ntp servers to add to the machine or firewall. [optional] - --partition string partition/datacenter where the machine is created. [required, except for reserved machines] - --placement-labels strings placement tags used for rack spreading - -p, --project string Project where the machine should belong to. [required] - --size string Size of the machine. [required, except for reserved machines] - --skip-security-prompts skips security prompt for bulk operations - -i, --ssh-public-key string SSH public key for access via ssh and console. [optional] - Can be either the public key as string, or pointing to the public key file to use e.g.: "@~/.ssh/id_rsa.pub". - If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order. - --timestamps when used with --file (bulk operation): prints timestamps in-between the operations - --userdata string cloud-init.io compatible userdata. [optional] - Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg". + --allocation-type string allocation type, can be either machine|firewall (default "machine") + --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. + --description string Description of the machine to create. [optional] + --dns-servers strings dns servers to add to the machine or firewall. [optional] + -f, --file string filename of the create or update request in yaml format, or - for stdin. + + Example: + $ metalctlv2 machine describe machine-1 -o yaml > machine.yaml + $ vi machine.yaml + $ # either via stdin + $ cat machine.yaml | metalctlv2 machine create -f - + $ # or via file + $ metalctlv2 machine create -f machine.yaml + + the file can also contain multiple documents and perform a bulk operation. + + --filesystem-layout string Filesystemlayout to use during machine installation. [optional] + -h, --help help for create + --hostname string Hostname of the machine. [required] + --image string OS Image to install. [required] + --labels strings labels to add to the machine, use it like: --labels "a=b" or --labels "a=". + --name string Name of the machine. [optional] + --networks strings Adds a network. Usage: [--networks NETWORK[:ip[;ip]][,NETWORK[:ip[;ip]]... + NETWORK specifies the name or id of an existing network. + IPs can be added per network colon separated, these ips must be already allocated upfront. If no ip(s) are specified per network, one ip per network is allocated. + + --ntp-servers strings ntp servers to add to the machine or firewall. [optional] + --partition string partition/datacenter where the machine is created. [required, except for reserved machines] + --placement-labels strings placement tags used for rack spreading + -p, --project string Project where the machine should belong to. [required] + --size string Size of the machine. [required, except for reserved machines] + --skip-security-prompts skips security prompt for bulk operations + -i, --ssh-public-key stringArray SSH public key for access via ssh and console. [optional] + Multiple keys can be passed by doing -i [key] -i [key] ... + Can be either the public keys as strings, or pointing to the public keys file to use e.g.: "@~/.ssh/id_rsa.pub". + If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order. + --timestamps when used with --file (bulk operation): prints timestamps in-between the operations + --userdata string cloud-init.io compatible userdata. [optional] + Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg". ``` ### Options inherited from parent commands diff --git a/go.mod b/go.mod index 3beefa4..cddade4 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,15 @@ module github.com/metal-stack/cli -go 1.27 +go 1.27.3 require ( - connectrpc.com/connect v1.20.0 - connectrpc.com/validate v0.6.0 - github.com/dustin/go-humanize v1.0.1 + connectrpc.com/connect v1.21.1 + connectrpc.com/validate v0.9.0 + github.com/dustin/go-humanize v1.1.0 github.com/fatih/color v1.19.0 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 - github.com/metal-stack/api v0.8.0 + github.com/metal-stack/api v0.8.3 github.com/metal-stack/metal-console v0.8.2 github.com/metal-stack/metal-lib v0.26.4 github.com/metal-stack/v v1.0.3 @@ -17,7 +17,7 @@ require ( github.com/spf13/cobra v1.10.2 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.12.1 - google.golang.org/grpc v1.83.2 + google.golang.org/grpc v1.84.0 google.golang.org/protobuf v1.36.12 sigs.k8s.io/yaml v1.6.0 ) @@ -28,6 +28,7 @@ require ( buf.build/go/protoyaml v0.7.0 // indirect cel.dev/cel-go v0.32.0 // indirect cel.dev/expr v0.25.3 // indirect + connectrpc.com/connect/v2 v2.0.0 // indirect filippo.io/edwards25519 v1.2.0 // indirect github.com/akutz/memconn v0.1.0 // indirect github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e // indirect @@ -41,16 +42,16 @@ require ( github.com/creachadair/msync v0.10.1 // indirect github.com/dblohm7/wingoes v0.0.0-20260526185140-fb298caac7ca // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect - github.com/fxamacker/cbor/v2 v2.9.3 // indirect - github.com/gaissmai/bart v0.29.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.6 // indirect + github.com/gaissmai/bart v0.30.0 // indirect github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3 // indirect - github.com/go-openapi/errors v0.22.8 // indirect - github.com/go-openapi/strfmt v0.27.2 // indirect + github.com/go-openapi/errors v0.22.9 // indirect + github.com/go-openapi/strfmt v0.27.4 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect - github.com/goccy/go-json v0.10.6 // indirect + github.com/goccy/go-json v0.11.2 // indirect github.com/goccy/go-yaml v1.19.2 // indirect - github.com/godbus/dbus/v5 v5.2.2 // indirect + github.com/godbus/dbus/v5 v5.2.4 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/btree v1.1.3 // indirect @@ -58,57 +59,57 @@ require ( github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jsimonetti/rtnetlink v1.4.2 // indirect - github.com/klauspost/compress v1.20.0 // indirect + github.com/klauspost/compress v1.20.3 // indirect github.com/klauspost/connect-compress/v2 v2.1.1 // indirect - github.com/mattn/go-colorable v0.1.15 // indirect + github.com/mattn/go-colorable v0.1.16 // indirect github.com/mattn/go-isatty v0.0.24 // indirect - github.com/mattn/go-runewidth v0.0.28 // indirect + github.com/mattn/go-runewidth v0.0.31 // indirect github.com/mdlayher/netlink v1.11.2 // indirect - github.com/mdlayher/socket v0.6.1 // indirect - github.com/minio/minlz v1.2.0 // indirect + github.com/mdlayher/socket v0.8.0 // indirect + github.com/minio/minlz v1.2.3 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/oklog/ulid/v2 v2.1.2 // indirect github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect github.com/olekukonko/errors v1.3.0 // indirect - github.com/olekukonko/ll v0.1.8 // indirect - github.com/olekukonko/tablewriter v1.1.4 // indirect + github.com/olekukonko/ll v0.1.9 // indirect + github.com/olekukonko/tablewriter v1.1.5 // indirect github.com/pelletier/go-toml/v2 v2.4.3 // indirect - github.com/pires/go-proxyproto v0.15.0 // indirect + github.com/pires/go-proxyproto v0.16.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/safchain/ethtool v0.7.0 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/stretchr/objx v0.5.3 // indirect + github.com/stretchr/objx v0.8.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tailscale/certstore v0.1.1-0.20260409135935-3638fb84b77d // indirect github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect github.com/tailscale/hujson v0.0.0-20260727124030-b80ff77dac4f // indirect github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect - github.com/tailscale/web-client-prebuilt v0.0.0-20251127225136-f19339b67368 // indirect - github.com/tailscale/wireguard-go v0.0.0-20260715223240-2e01ba5b00f0 // indirect + github.com/tailscale/web-client-prebuilt v0.0.0-20260917222731-e0ed2d0d0fea // indirect + github.com/tailscale/wireguard-go v0.0.0-20260928213032-417aef361226 // indirect github.com/x448/float16 v0.8.4 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect go4.org/netipx v0.0.0-20260823151212-3075585bcbeb // indirect - golang.org/x/crypto v0.56.0 // indirect - golang.org/x/exp v0.0.0-20260824195058-e88cd73687aa // indirect - golang.org/x/net v0.58.0 // indirect - golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.22.0 // indirect - golang.org/x/sys v0.47.0 // indirect - golang.org/x/term v0.45.0 // indirect - golang.org/x/text v0.41.0 // indirect - golang.org/x/time v0.15.0 // indirect + golang.org/x/crypto v0.58.0 // indirect + golang.org/x/exp v0.0.0-20261014143641-f0251eb4aa3e // indirect + golang.org/x/net v0.61.0 // indirect + golang.org/x/oauth2 v0.37.0 // indirect + golang.org/x/sync v0.24.0 // indirect + golang.org/x/sys v0.49.0 // indirect + golang.org/x/term v0.47.0 // indirect + golang.org/x/text v0.43.0 // indirect + golang.org/x/time v0.16.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v1.0.1 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260831171406-18b4a7587f8a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260831171406-18b4a7587f8a // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20261019180522-ce908d29299b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20261019180522-ce908d29299b // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8 // indirect - k8s.io/apimachinery v0.36.4 // indirect - sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect - tailscale.com v1.102.3 // indirect + gvisor.dev/gvisor v0.0.0-20260915211658-a6f909f08a72 // indirect + k8s.io/apimachinery v0.37.1 // indirect + sigs.k8s.io/json v0.0.0-20260909141634-11ed52e25bc5 // indirect + tailscale.com v1.104.2 // indirect ) diff --git a/go.sum b/go.sum index af07d3e..b4412a0 100644 --- a/go.sum +++ b/go.sum @@ -10,16 +10,18 @@ cel.dev/cel-go v0.32.0 h1:irvpFKr5EuGPyxeME03ERh0rii1TX+BDAnB9eL3IvNk= cel.dev/cel-go v0.32.0/go.mod h1:DnVip7tpJSsgZymwfT+m1tnEVy3ivAjSMXPx12YrMkU= cel.dev/expr v0.25.3 h1:A2jO8jwOugrrovveCWfj0KEZOfqiLgAcwjpHPhzIGw0= cel.dev/expr v0.25.3/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= -connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= -connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= -connectrpc.com/validate v0.6.0 h1:DcrgDKt2ZScrUs/d/mh9itD2yeEa0UbBBa+i0mwzx+4= -connectrpc.com/validate v0.6.0/go.mod h1:ihrpI+8gVbLH1fvVWJL1I3j0CfWnF8P/90LsmluRiZs= +connectrpc.com/connect v1.21.1 h1:h2kacdlzXpZU2OQFSv98xkjYXNUSr/ptxmGVbS/+CRM= +connectrpc.com/connect v1.21.1/go.mod h1:fhMcVJ5w6r/yTYhnkEbW6+sIF7OZ5Ay7KYgmfebh2ek= +connectrpc.com/connect/v2 v2.0.0 h1:PVVpWl2Xv9dIWN2gijs4HK40NSnPFzLqCEEmZ8fCUQ8= +connectrpc.com/connect/v2 v2.0.0/go.mod h1:N32OLrstcPUzkykFynnefFro3+xzSdOrZlK2jHmS/xo= +connectrpc.com/validate v0.9.0 h1:NLl+dbx87CZh1LId4FF87t92L5tsdmS0qDXxjZRe054= +connectrpc.com/validate v0.9.0/go.mod h1:dBEUzscHj4InQpm6J5xF8zX51MIUAPWZ7Jq8aNXRY9Y= filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc= filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA= -github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= -github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= @@ -30,109 +32,113 @@ github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYW github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/avast/retry-go/v4 v4.7.0 h1:yjDs35SlGvKwRNSykujfjdMxMhMQQM0TnIjJaHB+Zio= github.com/avast/retry-go/v4 v4.7.0/go.mod h1:ZMPDa3sY2bKgpLtap9JRUgk2yTAba7cgiFhqxY2Sg6Q= -github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek= -github.com/aws/aws-sdk-go-v2 v1.42.1/go.mod h1:5pKeft2eJj+gElQ38Jqg4ibCqh+/AK33/0X3hip7IjM= -github.com/aws/aws-sdk-go-v2/config v1.32.17 h1:FpL4/758/diKwqbytU0prpuiu60fgXKUWCpDJtApclU= -github.com/aws/aws-sdk-go-v2/config v1.32.17/go.mod h1:OXqUMzgXytfoF9JaKkhrOYsyh72t9G+MJH8mMRaexOE= -github.com/aws/aws-sdk-go-v2/credentials v1.19.16 h1:r3RJBuU7X9ibt8RHbMjWE6y60QbKBiII6wSrXnapxSU= -github.com/aws/aws-sdk-go-v2/credentials v1.19.16/go.mod h1:6cx7zqDENJDbBIIWX6P8s0h6hqHC8Avbjh9Dseo27ug= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 h1:UuSfcORqNSz/ey3VPRS8TcVH2Ikf0/sC+Hdj400QI6U= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23/go.mod h1:+G/OSGiOFnSOkYloKj/9M35s74LgVAdJBSD5lsFfqKg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 h1:xM/Is9cKMHa8Jj8zkvWhvrFkZsXJV9E+BB4g0HW0duQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30/go.mod h1:WueJeNDZvK1fMYEWJIkcivBfEzUkTpBhzlrUKKY8EuA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 h1:jn46zC9LdsVR/ZpMIJqMqb8hHv31BlLx3ulVqNspUOk= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30/go.mod h1:1hTMsAgbdS/AtUi4bw8+gUuh1pceo+eXRLfpSuSQj3M= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 h1:mbRIur/BiHK6SKPjoBIXSE/hJ6g6JGRLuxQy1jGjlN4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13/go.mod h1:ITg9em2KbJx1s0y4aqRX5OYWG6HBZ5TVR//OdpEZ2CQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 h1:/Z5jmNrKsSD7EmDjzAPsm/3L9IuOkzaynklJZ1qX7S4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30/go.mod h1:lEzEZnOosE7zi8Z6royW1cFJTD9fpab4Ul1SBrllewk= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 h1:TdJ+HdzOBhU8+iVAOGUTU63VXopcumCOF1paFulHWZc= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.11/go.mod h1:R82ZRExE/nheo0N+T8zHPcLRTcH8MGsnR3BiVGX0TwI= -github.com/aws/aws-sdk-go-v2/service/ssm v1.45.0 h1:IOdss+igJDFdic9w3WKwxGCmHqUxydvIhJOm9LJ32Dk= -github.com/aws/aws-sdk-go-v2/service/ssm v1.45.0/go.mod h1:Q7XIWsMo0JcMpI/6TGD6XXcXcV1DbTj6e9BKNntIMIM= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 h1:7byT8HUWrgoRp6sXjxtZwgOKfhss5fW6SkLBtqzgRoE= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.17/go.mod h1:xNWknVi4Ezm1vg1QsB/5EWpAJURq22uqd38U8qKvOJc= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 h1:+1Kl1zx6bWi4X7cKi3VYh29h8BvsCoHQEQ6ST9X8w7w= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21/go.mod h1:4vIRDq+CJB2xFAXZ+YgGUTiEft7oAQlhIs71xcSeuVg= -github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 h1:F/M5Y9I3nwr2IEpshZgh1GeHpOItExNM9L1euNuh/fk= -github.com/aws/aws-sdk-go-v2/service/sts v1.42.1/go.mod h1:mTNxImtovCOEEuD65mKW7DCsL+2gjEH+RPEAexAzAio= -github.com/aws/smithy-go v1.27.3 h1:F3Zb497UhhskkfpJmfkXswyo+t0sh9OTBnIHjogWbVY= -github.com/aws/smithy-go v1.27.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= -github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02 h1:bXAPYSbdYbS5VTy92NIUbeDI1qyggi+JYh5op9IFlcQ= -github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02/go.mod h1:k08r+Yj1PRAmuayFiRK6MYuR5Ve4IuZtTfxErMIh0+c= +github.com/aws/aws-sdk-go-v2 v1.46.0 h1:1kt7m/EKcEHt5mlyyxx9cSlMddRPIKbjb6DIQsu4HPk= +github.com/aws/aws-sdk-go-v2 v1.46.0/go.mod h1:bttEH6JqnUL8LepvDVfdrds/fZ5bCIxzpe3abyUrhDU= +github.com/aws/aws-sdk-go-v2/config v1.33.3 h1:h090b3O5S17bF87/0ysHZuIT/7DCb4EBRFQX2PMVPCw= +github.com/aws/aws-sdk-go-v2/config v1.33.3/go.mod h1:YYDB1kTejxbfAbEVUqgCtkVp26xvNCHev9cLKABMGAk= +github.com/aws/aws-sdk-go-v2/credentials v1.20.3 h1:tToOYM/LXev4NpfWlIYGDvBvjHmJ3HXpRU9ppl+pM6k= +github.com/aws/aws-sdk-go-v2/credentials v1.20.3/go.mod h1:wfGneWyncO7p67wqXV2IQhPk14JqIc25woKlaArT3WI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.2 h1:Ldv7RPHs7qwwTscRjAl3YBud32f3BvdAGRmSvAx5L38= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.2/go.mod h1:XyK6UV8xbo66ysVqLd2783C09pBYHOm8aKTRV5DVJ30= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.2 h1:q/PSLGuRWCChWg+dLnb9dWOnrCxJtnboXbBtFoqqRrI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.2/go.mod h1:TD1jvU2LvXkJexct5vBqcd8QlNXh5EmRUeL/Z32p0n4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.2 h1:6fl86IPqKEXoySqiOWdfgbEp9OVbn44zTfEICNEBDhY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.2/go.mod h1:63HDfhFkdzBpI8WGXTSKUHPKS6mqldj4u3LJW7RZtSU= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.2 h1:XMgIRS+uW9F3yFKnXGRrI9pkHi99CXTmoz2kz2/TGBA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.5.2/go.mod h1:vorxDzK+n3jiv9a5ST/LG0Eu9cSv1CRdKTpG6pDMs+M= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 h1:bAdDl/HkGCcGPoe25ToSHEw23VIxt6CT5fLcg111BKg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19/go.mod h1:KaUzbLxv4CeSxh6ZCl9B4m7CuFenS8kUEaDs+f/DQr4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.2 h1:ZtHYnumr6QyxhzEzNZwzQTFJEXOswrZqTTkRxthwvr4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.2/go.mod h1:a1NXrYpBd311gBzn1UI5UzJyyvXktM4xNh/ydPiPpqY= +github.com/aws/aws-sdk-go-v2/service/signin v1.9.0 h1:c3k+k/CS4L+sAIH6fxikL+g5g2LpeNczaoyjjw1iMKI= +github.com/aws/aws-sdk-go-v2/service/signin v1.9.0/go.mod h1:AGIoQg99fBrOIQnF78TLx4lj18mc4gZ0hJx1UaLIFM4= +github.com/aws/aws-sdk-go-v2/service/ssm v1.77.0 h1:JqKSBJlS68F4nxoPLwD7tB3lJ3gWEK9p+7eOiBE/lsM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.77.0/go.mod h1:5TMMHmQGjCODMeIopSNfxkan11jG0SmFpyjcMvCLzHA= +github.com/aws/aws-sdk-go-v2/service/sso v1.37.0 h1:+rqBaOq7jzInjY8M12hr+zEe85JpRll9BjMx38r33Ok= +github.com/aws/aws-sdk-go-v2/service/sso v1.37.0/go.mod h1:XFlVwUsw3sYh8Hw37umYVJnrcWrwXWRxbNw/JY0bblw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.42.0 h1:hzM3GslEAOBcLn3DHH6ENToFi+vXP+n02W+x6zejAIM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.42.0/go.mod h1:588e7skMkYIYkSUseT8E3WKFfbAfrA1bj3Zf+qxJtJY= +github.com/aws/aws-sdk-go-v2/service/sts v1.49.0 h1:N7Ey8obY3uSui+cxl0OUzFlFmkxSucoJnrniFhw+cLc= +github.com/aws/aws-sdk-go-v2/service/sts v1.49.0/go.mod h1:zMBwjSf4Pt8a1OHYiZ5rPD0PJRK1kQrUaxhS/Dbld8E= +github.com/aws/smithy-go v1.28.1 h1:R/nXH00c8qcfCzQVELtRw+eLQWtzv+VAIEFJ1/xxXlQ= +github.com/aws/smithy-go v1.28.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/axiomhq/hyperloglog v0.2.6 h1:sRhvvF3RIXWQgAXaTphLp4yJiX4S0IN3MWTaAgZoRJw= +github.com/axiomhq/hyperloglog v0.2.6/go.mod h1:YjX/dQqCR/7QYX0g8mu8UZAjpIenz1FKM71UEsjFoTo= +github.com/benbjohnson/immutable v0.4.3 h1:GYHcksoJ9K6HyAUpGxwZURrbTkXA0Dh4otXGqbhdrjA= +github.com/benbjohnson/immutable v0.4.3/go.mod h1:qJIKKSmdqz1tVzNtst1DZzvaqOU1onk1rc03IeM3Owk= +github.com/bradfitz/reco v0.0.0-20260929154613-b883fbd17e3f h1:jdXGSp5Ge5/kzikuxGOw9+6HSStUjkNBJZjGNtpItek= +github.com/bradfitz/reco v0.0.0-20260929154613-b883fbd17e3f/go.mod h1:oiCPXxBoDKSkb/RGEZwAZk8y/fwDlQ1vYlBbNRxPysw= github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4= github.com/brianvoe/gofakeit/v6 v6.28.0/go.mod h1:Xj58BMSnFqcn/fAQeSK+/PLtC5kSb7FJIq4JyGa8vEs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= -github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= +github.com/cilium/ebpf v0.22.0 h1:v2ktp0roffpMOj2MMf3idtCQZOsAoC4BJbAJN+ke2bY= +github.com/cilium/ebpf v0.22.0/go.mod h1:CDzZbe2hC5JjlDC+CY3KFCzlYwN4gbxppYM+Z10bQt4= github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/coder/websocket v1.8.15 h1:6B2JPeOGlpff2Uz6vOEH1Vzpi0iUz20A+lPVhPHtNUA= github.com/coder/websocket v1.8.15/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= -github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= -github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc= +github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creachadair/mds v0.30.5 h1:JtylThbC3wUndriq7yZiY23AD0L7ZaKSvx3XQwQk8FI= -github.com/creachadair/mds v0.30.5/go.mod h1:NGUd6kGUG0qQd2kgGOqb8NzakLnSmWZ5be2pHZsrBN4= +github.com/creachadair/mds v0.31.0 h1:h4SXXgallvZfD8CFQnQNAOtBkUGpZjPwNBRQpHpHM/g= +github.com/creachadair/mds v0.31.0/go.mod h1:IZ3oLffgVNZ4O5WXTPxx7EX5ilSl1ypdv5FekYyynyI= github.com/creachadair/msync v0.10.1 h1:14jT5Ujob64Zp2D3ZcUidayDMoXikhmYN8xBxEuPKPk= github.com/creachadair/msync v0.10.1/go.mod h1:dFf4Z0cxE2nibFmAdq5OqTuGn++GgEqA9JuKH+7ceSA= -github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc= -github.com/creachadair/taskgroup v0.13.2/go.mod h1:i3V1Zx7H8RjwljUEeUWYT30Lmb9poewSb2XI1yTwD0g= +github.com/creachadair/taskgroup v0.14.4 h1:ttR8StLWmYA1O6x96YlTpQLXjKyRpO4RBo+OcO6W6C0= +github.com/creachadair/taskgroup v0.14.4/go.mod h1:uhCtIEsa7zpeMAFixddhCYjbJi7e4JMyU7OXUygkSsg= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/dblohm7/wingoes v0.0.0-20260526185140-fb298caac7ca h1:h1Awca4lQOspNR/2eeo04Ricn5NixDX9mb17WSAgLhQ= github.com/dblohm7/wingoes v0.0.0-20260526185140-fb298caac7ca/go.mod h1:2TGl1jRJrRpbzykmg7asHm3h08TqutUgQqY5v9k/g3c= -github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= -github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mTEIGbvhcYU3S8+uSNkuMjx/qZFfhtM= +github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yezR0y7jJ5pceLHthLaYf4bA5T14B6q39S4q2Q= github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e/go.mod h1:YTIHhz/QFSYnu/EhlF2SpU2Uk+32abacUYA5ZPljz1A= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dustin/go-humanize v1.1.0 h1:dbKTrvD0klcbBV/h4AWJdMuZogJACoMlvWIWZ5b2xWg= +github.com/dustin/go-humanize v1.1.0/go.mod h1:hc1CvRkJMsgxqjmjMQF3QNRAZBwY8AXBAzKYoSX9sFI= github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= -github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q= -github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/gaissmai/bart v0.29.0 h1:wO6HGE8g9YE0Wm0bCpYxwRzfQ4+fbJKOhL64e5ACGCI= -github.com/gaissmai/bart v0.29.0/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c= +github.com/fxamacker/cbor/v2 v2.9.6 h1:NHZPxuUjJXQjX9itA785y/5NKSlI4HQ+S7noZsmI7hs= +github.com/fxamacker/cbor/v2 v2.9.6/go.mod h1:4EaZp6ClVunETjQ4GHmGNzysDK91Lr+r6Yz6tJqzVCw= +github.com/gaissmai/bart v0.30.0 h1:K1oTSQ6Nf76bhrgxeTqzZa4hE0M9x4xDfL6n6UG67Sc= +github.com/gaissmai/bart v0.30.0/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3 h1:UADEEmDKgfXbtnGJZ97beY5XLo9ZechG1nlU4KnRrkE= github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/errors v0.22.8 h1:oP7sW7TWc3wFFjrzzj0nI83H2qMBkNjNfSd+XRejk/I= -github.com/go-openapi/errors v0.22.8/go.mod h1:BuUoHcYrU6E7V9gfj1I5wLQqgtIHnup/alXZ8KdgQ0w= -github.com/go-openapi/strfmt v0.27.2 h1:SG32SlbwNy92s0KJiVxt2joJeFdqIYHvwrA0OU6HqzQ= -github.com/go-openapi/strfmt v0.27.2/go.mod h1:M4CKsMO0Fb8qR10+1Ra75wCKNNquy+Vj+4LWZrhTo2E= -github.com/go-openapi/testify/v2 v2.7.0 h1:bycOreEj6wfBvijg3YFogZ/sFjTCDmQnwSodSzHa3X8= -github.com/go-openapi/testify/v2 v2.7.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= +github.com/go-openapi/errors v0.22.9 h1:HI9+SyVYiRzyeBQGv0CbWbQa+u2S0nny7G7AhY+UMiM= +github.com/go-openapi/errors v0.22.9/go.mod h1:R73q66sXP2smzAGgFOI4nqtusRK2xN5pYCjsij+KX58= +github.com/go-openapi/strfmt v0.27.4 h1:E1xsvHb8R9vsuYru4TP2PVVTv9AIgSFAUACUZrFQfCI= +github.com/go-openapi/strfmt v0.27.4/go.mod h1:SCOff81PPhU26acBiW96jHaFycEbT2nkQRvojM+V2z0= +github.com/go-openapi/testify/v2 v2.8.0 h1:19QDx5b57p8KjO2E4sgs/woL4Akp+FGLRlVm2xn0Rho= +github.com/go-openapi/testify/v2 v2.8.0/go.mod h1:4gUN8jC+RqOE2qjW/vDmfyTvl5BCht4qL7oca0odrak= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/go4org/hashtriemap v0.0.0-20251130024219-545ba229f689 h1:0psnKZ+N2IP43/SZC8SKx6OpFJwLmQb9m9QyV9BC2f8= -github.com/go4org/hashtriemap v0.0.0-20251130024219-545ba229f689/go.mod h1:OGmRfY/9QEK2P5zCRtmqfbCF283xPkU2dvVA4MvbvpI= +github.com/go4org/hashtriemap v0.0.0-20260925222741-44e5305f85d9 h1:J8S+Ms89nvHX1F9Ma2m3KhdTl41ZhbFKMyAJqvDA+iE= +github.com/go4org/hashtriemap v0.0.0-20260925222741-44e5305f85d9/go.mod h1:OGmRfY/9QEK2P5zCRtmqfbCF283xPkU2dvVA4MvbvpI= github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737 h1:cf60tHxREO3g1nroKr2osU3JWZsJzkfi7rEg+oAB0Lo= github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737/go.mod h1:MIS0jDzbU/vuM9MC4YnBITCv+RYuTRq8dJzmCrFsK9g= -github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU= -github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.11.2 h1:jdZv93Tt4ioR8yW1CoNsvSxrcZlCXAUU1aZXN7gpXUA= +github.com/goccy/go-json v0.11.2/go.mod h1:3NdmfEkZlB7YI5UFw/qdFKq8XN1aiWR0YyRPWZNQltY= github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ= -github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= +github.com/godbus/dbus/v5 v5.2.4 h1:F2gUCy++NMIxGmo9J+z5le/+ZC8W1OgeR51P4i9ZB/U= +github.com/godbus/dbus/v5 v5.2.4/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= @@ -143,10 +149,10 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-tpm v0.9.4 h1:awZRf9FwOeTunQmHoDYSHJps3ie6f1UlhS1fOdPEt1I= -github.com/google/go-tpm v0.9.4/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI= -github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4= +github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= +github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/nftables v0.3.0 h1:bkyZ0cbpVeMHXOrtlFc8ISmfVqq5gPJukoYieyVmITg= +github.com/google/nftables v0.3.0/go.mod h1:BCp9FsrbF1Fn/Yu6CLUc9GGZFw/+hsxfluNXXmxBfRM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= @@ -157,16 +163,16 @@ github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeV github.com/illarion/gonotify/v3 v3.0.2/go.mod h1:HWGPdPe817GfvY3w7cx6zkbzNZfi3QjcBm/wgVvEL1U= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/insomniacslk/dhcp v0.0.0-20240204152450-ca2dc33955c1 h1:L3pm9Kf2G6gJVYawz2SrI5QnV1wzHYbqmKnSHHXJAb8= -github.com/insomniacslk/dhcp v0.0.0-20240204152450-ca2dc33955c1/go.mod h1:izxuNQZeFrbx2nK2fAyN5iNUB34Fe9j0nK4PwLzAkKw= -github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJBcYE71g= -github.com/jellydator/ttlcache/v3 v3.1.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/insomniacslk/dhcp v0.0.0-20260901064844-234b97448fae h1:nXGg65fXsylSUTNNWwvHuQsXev7mhIzQTnZREPTbWzs= +github.com/insomniacslk/dhcp v0.0.0-20260901064844-234b97448fae/go.mod h1:tGfUTcnFYGYvVNCaZZhwlJySU/fQQxh9TmpsFzWXnnY= +github.com/jellydator/ttlcache/v3 v3.4.1 h1:bOdXmXiycyK6E6Qjyuj5vl+/vU3SCOoDs8a86NbHjAQ= +github.com/jellydator/ttlcache/v3 v3.4.1/go.mod h1:j7LO12PNghFg5+0v9budMAT4rDK4JY969jb9vOdOBBk= github.com/jsimonetti/rtnetlink v1.4.2 h1:Df9w9TZ3npHTyDn0Ev9e1uzmN2odmXd0QX+J5GTEn90= github.com/jsimonetti/rtnetlink v1.4.2/go.mod h1:92s6LJdE+1iOrw+F2/RO7LYI2Qd8pPpFNNUYW06gcoM= -github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= -github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= +github.com/kamstrup/intmap v0.5.2 h1:qnwBm1mh4XAnW9W9Ue9tZtTff8pS6+s6iKF6JRIV2Dk= +github.com/kamstrup/intmap v0.5.2/go.mod h1:gWUVWHKzWj8xpJVFf5GC0O26bWmv3GqdnIX/LMT6Aq4= +github.com/klauspost/compress v1.20.3 h1:zWNoFqq/lSuYQRim3dUXlXeA0IqwuZGicdG5ZTfY5j4= +github.com/klauspost/compress v1.20.3/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/klauspost/connect-compress/v2 v2.1.1 h1:ycZNp4rWOZBodVE2Ls5AzK4aHkyK+GteEfzRZgKNs+c= github.com/klauspost/connect-compress/v2 v2.1.1/go.mod h1:9oilsPHJMzGKkjafSBk9J7iVo4mO+dw0G0KSdVpnlVE= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= @@ -177,32 +183,32 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= -github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-colorable v0.1.16 h1:+2YjeAe7xP1OQbZW1jERPWWCDLlNqFNCvjiqGiAt84A= +github.com/mattn/go-colorable v0.1.16/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= -github.com/mattn/go-runewidth v0.0.28 h1:rPyg2ybwEKPebvpzVWe1gKBkH8EQFkxO4Y0hjBeLaBU= -github.com/mattn/go-runewidth v0.0.28/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8= -github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw= -github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= +github.com/mattn/go-runewidth v0.0.31 h1:1oCV4ReTlosDBc6rYRw5cL8S/4y8iv5oRl4SJ5IBgwo= +github.com/mattn/go-runewidth v0.0.31/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8= +github.com/mdlayher/genetlink v1.4.0 h1:f/Xs7Y2T+GyX9b3dbiUhnLE9InGs5F9RxJ2JwBMl71o= +github.com/mdlayher/genetlink v1.4.0/go.mod h1:d1hrKr8fwZU2JkcAtQUAzeTrI7nbgQSl+5k1cC0biSA= github.com/mdlayher/netlink v1.11.2 h1:HKh2jqe+omdSWcQ88nrT7INE61B0NXfiSPFdgL4YbNI= github.com/mdlayher/netlink v1.11.2/go.mod h1:uT2Yc/QLaZubzDpZIBi9d4GoeLwtp3x1AMeqSRrK2sA= github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ3c= github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE= -github.com/mdlayher/socket v0.6.1 h1:M7uj2NtuujUY4mYr1C57NmfNiRHbkKpnBxO856lsc3A= -github.com/mdlayher/socket v0.6.1/go.mod h1:+/SGtqc9V+5dAuRgQsU0fGBI+oRDiW7O2Obx10OIWfg= -github.com/metal-stack/api v0.8.0 h1:olAQtHx7uv3f/jaKKo7aVILhZgO5McQTLeKfS0FkolM= -github.com/metal-stack/api v0.8.0/go.mod h1:rWdj0dTAg2w/WuQhIZ+JVp9b68v6VVCm1k7sLx4U+PQ= +github.com/mdlayher/socket v0.8.0 h1:1lIVvHAs3sT623kPkPDa+I0nLVusskwnpWzp6ZUcNyc= +github.com/mdlayher/socket v0.8.0/go.mod h1:EhNb63aXqexVoTJDblxvDOSuIGIJinC4H5ZktnaJ6Rk= +github.com/metal-stack/api v0.8.3 h1:ii29tTXP1HLN6dUGLwgFjBlDiz0BHTtla5gUJtxPe34= +github.com/metal-stack/api v0.8.3/go.mod h1:U0CJxoo35jpS87HNDbVDrilxR106TnE5rJ/xSmgQkPg= github.com/metal-stack/metal-console v0.8.2 h1:Y86penzEROJKcLica1PeE2ddtr9G0/u16HiCAYXaxxU= github.com/metal-stack/metal-console v0.8.2/go.mod h1:ZkselOaxF/iELFL9Tku3maXgpX4DM0CHjoG7CGuky6E= github.com/metal-stack/metal-lib v0.26.4 h1:Qg+JorX0AgQCkrCK07wvstGEoRcm/Y97E2UG5ZBAXjo= github.com/metal-stack/metal-lib v0.26.4/go.mod h1:cNXjPBs8SFnjqfBobuSbm5mDk6E/jS8PVeIOrV/7POE= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= -github.com/minio/minlz v1.2.0 h1:6IOBuiHg04QxvbFfgFLT/9sMaO/UhL7S+ApW1mK8q5A= -github.com/minio/minlz v1.2.0/go.mod h1:Ls9H7nlkASeCcdl5thjVD5Eraj6z+zGa7xtq57jIKD4= +github.com/miekg/dns v1.1.73 h1:uhT8nJxmTrPJYClxVxTCX+CVn6qnzSiybRk72Z6DgrE= +github.com/miekg/dns v1.1.73/go.mod h1:RW2Obtfd5NZHvOFe3zYG0W8koWOQtAzyHaLo8vASBuQ= +github.com/minio/minlz v1.2.3 h1:xUNhxBd8AlRJbJIsFkVmrN96gk9as9PjheVh3f9x90s= +github.com/minio/minlz v1.2.3/go.mod h1:xHhZ+MJmC2U4ssK/rSENsoyCfv0VFQo1mT6AdCA2RJ8= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -215,27 +221,27 @@ github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0= github.com/olekukonko/errors v1.3.0 h1:teJvgLGUEqMzBUms+Dj3/3szNqCG/Jdw9iDbum8fR6U= github.com/olekukonko/errors v1.3.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= -github.com/olekukonko/ll v0.1.8 h1:ysHCJRGHYKzmBSdz9w5AySztx7lG8SQY+naTGYUbsz8= -github.com/olekukonko/ll v0.1.8/go.mod h1:RPRC6UcscfFZgjo1nulkfMH5IM0QAYim0LfnMvUuozw= -github.com/olekukonko/tablewriter v1.1.4 h1:ORUMI3dXbMnRlRggJX3+q7OzQFDdvgbN9nVWj1drm6I= -github.com/olekukonko/tablewriter v1.1.4/go.mod h1:+kedxuyTtgoZLwif3P1Em4hARJs+mVnzKxmsCL/C5RY= +github.com/olekukonko/ll v0.1.9 h1:7twe+xnE6CSlfOlvGj0Finwnvr3CgWt25W33yuWNI6k= +github.com/olekukonko/ll v0.1.9/go.mod h1:RPRC6UcscfFZgjo1nulkfMH5IM0QAYim0LfnMvUuozw= +github.com/olekukonko/tablewriter v1.1.5 h1:4LoZSfMySpMQY3PT8RWJsJeuEuMIoo9xGRgvmqjg6IQ= +github.com/olekukonko/tablewriter v1.1.5/go.mod h1:+kedxuyTtgoZLwif3P1Em4hARJs+mVnzKxmsCL/C5RY= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY= github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= -github.com/pires/go-proxyproto v0.15.0 h1:dTshmNbFm/D+0+sbrxUuddPOZ5Y0B7c5NhtsBkm6LqI= -github.com/pires/go-proxyproto v0.15.0/go.mod h1:OXsCrKwrK2tXS9YrI5tkHx5xaQlO8FH3lFW76orFh24= -github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85CuiNk= -github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= +github.com/pires/go-proxyproto v0.16.0 h1:9KYT/fM3wpjT8bdMEj/7FBcoiUG1KyzEjRYnPu+vz7A= +github.com/pires/go-proxyproto v0.16.0/go.mod h1:n7yhg8yIfNl3KgYDCwBzmeUHNpKTVnUhcWpc7rV4RW4= +github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE= +github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0= +github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPTB1qyxiEo= +github.com/prometheus/client_model v0.6.3/go.mod h1:gpN5P9S7Rr6Yr92PiQ+Ixvhf6JZEkF1dnxsYL2aPBEM= +github.com/prometheus/common v0.71.0 h1:9KDAKb7Mj3HEVKyFCK6Dc/HIwlBzZIN2l7/lrHl3KK8= +github.com/prometheus/common v0.71.0/go.mod h1:CLJ5H8TEsGX8bl31BdMkfhIZ+QmZ9tBPPotUxUbfcmk= github.com/rodaine/protogofakeit v0.1.1 h1:ZKouljuRM3A+TArppfBqnH8tGZHOwM/pjvtXe9DaXH8= github.com/rodaine/protogofakeit v0.1.1/go.mod h1:pXn/AstBYMaSfc1/RqH3N82pBuxtWgejz1AlYpY1mI0= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.16.0 h1:O9DK+vNMDVGLr2BeZqmpLeMjiMNkuXfcqntWbZV6S5g= +github.com/rogpeppe/go-internal v1.16.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/safchain/ethtool v0.7.0 h1:rlJzfDetsVvT61uz8x1YIcFn12akMfuPulHtZjtb7Is= @@ -253,8 +259,8 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= -github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= -github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= +github.com/stretchr/objx v0.8.0 h1:rm9oMkeprG/wHifkZP4EuDww9S0mvEaQ/p9cXTNT4cw= +github.com/stretchr/objx v0.8.0/go.mod h1:xSzHnPHkdEv7vtgdQej8atlCuU1mdX+ELge8bn0hCsE= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/studio-b12/gowebdav v0.13.0 h1:OcwSg6IQHOFNdYHn3bPOHwSE8looG8N56Y5xTT1asqQ= @@ -267,26 +273,26 @@ github.com/tailscale/gliderssh v0.3.4-0.20260716005906-1a0f895faf28 h1:Azz5ILxxV github.com/tailscale/gliderssh v0.3.4-0.20260716005906-1a0f895faf28/go.mod h1:wn16Km1EZOX4UEAyaZa3dBwfFGOJ7neck40NcwosJUw= github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4= github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= -github.com/tailscale/golang-x-crypto v0.0.0-20260720153645-2ba0bf7866ed h1:uyvHhX1FQada0vVk8CSHa4tJT96EEAkTypaYz8Tq5Nc= -github.com/tailscale/golang-x-crypto v0.0.0-20260720153645-2ba0bf7866ed/go.mod h1:NC3xRCu4UR+m4n6ix8b6oLLbHa820Y0StbOQEdWTDo0= +github.com/tailscale/golang-x-crypto v0.0.0-20260720160339-c86ca1284b96 h1:m9EAsCu/afUkg9YkknXaRqMPl/omkUNRol5yB7hbG0Y= +github.com/tailscale/golang-x-crypto v0.0.0-20260720160339-c86ca1284b96/go.mod h1:NC3xRCu4UR+m4n6ix8b6oLLbHa820Y0StbOQEdWTDo0= github.com/tailscale/hujson v0.0.0-20260727124030-b80ff77dac4f h1:9hiVElpCmKzsBKQHkBqZ8LGzt82iLfM8egxr4sew+Ys= github.com/tailscale/hujson v0.0.0-20260727124030-b80ff77dac4f/go.mod h1:8/zr1Tv0+cKpVtGCEB/7YfRXr2TszsMxMXLaT8YuBgU= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA= github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc/go.mod h1:f93CXfllFsO9ZQVq+Zocb1Gp4G5Fz0b0rXHLOzt/Djc= -github.com/tailscale/web-client-prebuilt v0.0.0-20251127225136-f19339b67368 h1:0tpDdAj9sSfSZg4gMwNTdqMP592sBrq2Sm0w6ipnh7k= -github.com/tailscale/web-client-prebuilt v0.0.0-20251127225136-f19339b67368/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= +github.com/tailscale/web-client-prebuilt v0.0.0-20260917222731-e0ed2d0d0fea h1:ah5jt6ZnxMvNclt6kBBoLcMpLLjMA44PTsnov2y7gpU= +github.com/tailscale/web-client-prebuilt v0.0.0-20260917222731-e0ed2d0d0fea/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y= -github.com/tailscale/wireguard-go v0.0.0-20260715223240-2e01ba5b00f0 h1:CnIEL2n7Xql6Ux1k+Vu5S5ubDHCT/kxFgkKCY8FjefU= -github.com/tailscale/wireguard-go v0.0.0-20260715223240-2e01ba5b00f0/go.mod h1:6SerzcvHWQchKO2BfNdmquA77CHSECZuFl+D9fp4RnI= +github.com/tailscale/wireguard-go v0.0.0-20260928213032-417aef361226 h1:v3Lpj2iHPWQDqeCwemQPz4fWweIEMLqBkwJqCjRyJQc= +github.com/tailscale/wireguard-go v0.0.0-20260928213032-417aef361226/go.mod h1:rUelGmuK4UnSJYM5gl5Mknp6YbwwcL8+VAPMhNYe+jg= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg= -github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= -github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= -github.com/u-root/u-root v0.14.0 h1:Ka4T10EEML7dQ5XDvO9c3MBN8z4nuSnGjcd1jmU2ivg= -github.com/u-root/u-root v0.14.0/go.mod h1:hAyZorapJe4qzbLWlAkmSVCJGbfoU9Pu4jpJ1WMluqE= +github.com/tc-hib/winres v0.3.1 h1:CwRjEGrKdbi5CvZ4ID+iyVhgyfatxFoizjPhzez9Io4= +github.com/tc-hib/winres v0.3.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= +github.com/u-root/u-root v0.16.0 h1:wY40O83MBVks97+Is0WlFlOPSwKQMIrWP9R1IsrExg8= +github.com/u-root/u-root v0.16.0/go.mod h1:yL/XdSSW27PdGLgUh4MNRBy54mKM+TBLzpwiB4nwj90= github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM= github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= @@ -302,66 +308,67 @@ go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4 go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/netipx v0.0.0-20260823151212-3075585bcbeb h1:XBM4hvfwGAttkkiTIFfeigdfcL1xIfdKXqFdgiHGtDs= go4.org/netipx v0.0.0-20260823151212-3075585bcbeb/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= -golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= -golang.org/x/exp v0.0.0-20260824195058-e88cd73687aa h1:QSyA8ishJCyT21kER9KwNt0b7BM3iRK4x9QXhjN5Fdk= -golang.org/x/exp v0.0.0-20260824195058-e88cd73687aa/go.mod h1:zeBbvyFKDaLwa7CH/zI8KXt7gTl14SF7sO08Pl5jBCM= -golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= -golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= -golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= -golang.org/x/mod v0.39.0 h1:UF5zwQdCRRUpHfyPwr7d4UrGiVeldIsogtzWVnczL74= -golang.org/x/mod v0.39.0/go.mod h1:bvIbwjQ0HUFFf5AKukeeYQG4ZBUG9yxQbR9aEweIwYY= -golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= -golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= -golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= -golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/crypto v0.58.0 h1:COkYLr4k7nDI4r6QtMML2AfzeIswWHAJthLS6K/M/54= +golang.org/x/crypto v0.58.0/go.mod h1:Xh+kl5A+M0gMiWDytH2Hhr5Z7WbNCpv/eB/EFgfSk+w= +golang.org/x/exp v0.0.0-20261014143641-f0251eb4aa3e h1:HgI6W1OolKK6tcV74is+rl9SMT0njsHlp0TbQiGXI/A= +golang.org/x/exp v0.0.0-20261014143641-f0251eb4aa3e/go.mod h1:DBoxwWhjaW8DJJw/YeM4zpeOKMC1FMXSblsYy+1mFSw= +golang.org/x/exp/typeparams v0.0.0-20260811152304-ee035b5b010f h1:+lI8cDJ4uceLipg2f1ODay7fEuLkk0BIHXd6PB8icxo= +golang.org/x/exp/typeparams v0.0.0-20260811152304-ee035b5b010f/go.mod h1:PqrXSW65cXDZH0k4IeUbhmg/bcAZDbzNz3byBpKCsXo= +golang.org/x/image v0.46.0 h1:b1+oYj0Jbp6K5MDT4i4/eZpYlk3V8SJhhDKh6LBHAyQ= +golang.org/x/image v0.46.0/go.mod h1:3B3W05VGVQyuXucLINLjXKrqISASfi4Xj+iCVkLMwew= +golang.org/x/mod v0.42.0 h1:ICeL3t2L30ljSPHHxDnR4fqVcBt/zR2zJAb9juavmQg= +golang.org/x/mod v0.42.0/go.mod h1:u5fzIrRInkL8MaO1cbRkUHT64v303YIT5KEqpNr7jRs= +golang.org/x/net v0.61.0 h1:RR+6j/BTBCrggOLugxa+66R8FvoN6MHlzDlZIbN9YFw= +golang.org/x/net v0.61.0/go.mod h1:WgDCOTH8iwtB66T4/GfI94AHo/hhdb7Hah9NDseQfiI= +golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98= +golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= -golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= -golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= -golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= -golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= -golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= -golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= -golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= -golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= +golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA= +golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= +golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA= +golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= +golang.org/x/term v0.47.0 h1:cpyOwQkr2Nzxe2p6KnrTG7Ei2wtzjsuSjhpXXepZ/BM= +golang.org/x/term v0.47.0/go.mod h1:efAfAuG6RKABvg1ArGebRkvX6LXul14SM67o2e4mUCY= +golang.org/x/text v0.43.0 h1:1QivrlhwAsnMOcqgOdl9my7s9OyZl8O5/UGUTJVXoWc= +golang.org/x/text v0.43.0/go.mod h1:hbSIYA/amXcRXTFSZqh8tWHEoqRvvbKPJ2uz/KU+a+s= +golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE= +golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s= +golang.org/x/tools v0.52.0 h1:ryxg4U63oaUYk7uOLTF37n43f4qgtGvqV4Ioit1BaEs= +golang.org/x/tools v0.52.0/go.mod h1:ItcP5UNaVGG+Yc4eIYmaFLNJ4soEopkx5Y2d4lcEurs= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446 h1:cqHQ3AycTHvM2R7ikgyX57D+XvtcSnGylsLkOVhta/w= golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw= golang.zx2c4.com/wireguard/windows v1.0.1 h1:eOxiDVbywPC+ZQqvdCK7x+ZwWXKbYv50TtH8ysFIbw8= golang.zx2c4.com/wireguard/windows v1.0.1/go.mod h1:+fbT3FFdX4zzYDLwJh5+HPEcNN/3HyNdzhNSVsQM+zs= -google.golang.org/genproto/googleapis/api v0.0.0-20260831171406-18b4a7587f8a h1:i3TAXhpKc7TUP1VAPiBBrv45kamjoizCC3rOC0cAbOs= -google.golang.org/genproto/googleapis/api v0.0.0-20260831171406-18b4a7587f8a/go.mod h1:CvYJHpbzPlT0fb/PsgtAamdwru/GVxUsomFdXTpOTI8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260831171406-18b4a7587f8a h1:3Dnd1cDaZlB68lziofO+bJXpjOy8UfRv8Unt+yH8tQ4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260831171406-18b4a7587f8a/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA= -google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= -google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= +google.golang.org/genproto/googleapis/api v0.0.0-20261019180522-ce908d29299b h1:nB3spRIaSPtxJpxb0k41yljROvm2Jrwfs2pSNdKS5y8= +google.golang.org/genproto/googleapis/api v0.0.0-20261019180522-ce908d29299b/go.mod h1:9N4vtjEwvgQKEdlFVQO0M44ErhecQ9DCSQfGoZ51M6w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20261019180522-ce908d29299b h1:6WNWHZk91dp4gZ25642OALkuG1UVNZbwENJD19DnB8k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20261019180522-ce908d29299b/go.mod h1:OaIUM3+LpYcK2GXM4FTmhWoIq371Owdr+Cc7/BsYHHc= +google.golang.org/grpc v1.84.0 h1:soMyaPJ8pAak5PIQ0DGBUir0XRo2fRoMqhNWMLlLxO0= +google.golang.org/grpc v1.84.0/go.mod h1:ljCht0DrxQrXBDRTZp52Qxh3Ffk8CdYm2sj4O2QN2C0= google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8 h1:Zy8IV/+FMLxy6j6p87vk/vQGKcdnbprwjTxc8UiUtsA= -gvisor.dev/gvisor v0.0.0-20260224225140-573d5e7127a8/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q= +gvisor.dev/gvisor v0.0.0-20260915211658-a6f909f08a72 h1:EytKYr5WrVs+Aah/0xDO8ZAZZzS/iTEVC8ln4ipDbL0= +gvisor.dev/gvisor v0.0.0-20260915211658-a6f909f08a72/go.mod h1:8aLQqUBHDH8fY5y60lzmwDpMMbQCcT3EBfoSwhfaGCY= honnef.co/go/tools v0.8.1 h1:+JKf3xJ1ni4CwrhVg4/pqsfPGP6vNAXcKbMXJodYx3w= honnef.co/go/tools v0.8.1/go.mod h1:XA+OnlRA9EDh/ukGvXMNSZNKGwFQJ+5dER0ioUkOxks= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= -k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= -sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= -sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/apimachinery v0.37.1 h1:hGCYyvKHCwtwMitj2vU4vYx0Z16N9GyZk9BBnz0wDAE= +k8s.io/apimachinery v0.37.1/go.mod h1:jF84AyUi/IRIXRot5f+lm6MpxoWI+F1XgjaMmwCdTFw= +sigs.k8s.io/json v0.0.0-20260909141634-11ed52e25bc5 h1:k9jo7ED/fsfOcz3L1P20P5tjTNtsdQNwMOG2aKzHrl8= +sigs.k8s.io/json v0.0.0-20260909141634-11ed52e25bc5/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= -software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= -software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= -tailscale.com v1.102.3 h1:M1czCAtMuIcg+2Z+FBPbJyAk3ZEQGEFKnvHthtE1c6M= -tailscale.com v1.102.3/go.mod h1:47bv91Xbg4K1p5wti7F1dmKvUVWV5BXF78d9EWJ+d6c= +software.sslmate.com/src/go-pkcs12 v0.7.3 h1:JBQD3FDqYjTeyDAeZQklj2ar88ykBLtALloPJHyAauU= +software.sslmate.com/src/go-pkcs12 v0.7.3/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= +tailscale.com v1.104.2 h1:zBbSW0tI4Xi2PhrZEl9yt6oWay3l8A+M8scsTnZpyAk= +tailscale.com v1.104.2/go.mod h1:D+gqEyJjFnwIaojBLaKxUbOfEO3cRXOaFaOZ5BIvYqs= From 674ae63ac1f24d2607664e5c195c868e90f8de56 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Thu, 22 Oct 2026 20:27:51 +0200 Subject: [PATCH 4/5] Generate docs --- docs/admin/metalctlv2_admin_filesystem.md | 39 ++++++++++++++++ .../metalctlv2_admin_filesystem_apply.md | 46 +++++++++++++++++++ .../metalctlv2_admin_filesystem_create.md | 46 +++++++++++++++++++ .../metalctlv2_admin_filesystem_delete.md | 46 +++++++++++++++++++ .../metalctlv2_admin_filesystem_describe.md | 31 +++++++++++++ .../admin/metalctlv2_admin_filesystem_edit.md | 31 +++++++++++++ .../admin/metalctlv2_admin_filesystem_list.md | 33 +++++++++++++ .../metalctlv2_admin_filesystem_match.md | 40 ++++++++++++++++ .../metalctlv2_admin_filesystem_update.md | 46 +++++++++++++++++++ docs/metalctlv2_filesystem.md | 33 +++++++++++++ docs/metalctlv2_filesystem_describe.md | 31 +++++++++++++ docs/metalctlv2_filesystem_list.md | 33 +++++++++++++ 12 files changed, 455 insertions(+) create mode 100644 docs/admin/metalctlv2_admin_filesystem.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_apply.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_create.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_delete.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_describe.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_edit.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_list.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_match.md create mode 100644 docs/admin/metalctlv2_admin_filesystem_update.md create mode 100644 docs/metalctlv2_filesystem.md create mode 100644 docs/metalctlv2_filesystem_describe.md create mode 100644 docs/metalctlv2_filesystem_list.md diff --git a/docs/admin/metalctlv2_admin_filesystem.md b/docs/admin/metalctlv2_admin_filesystem.md new file mode 100644 index 0000000..bd92e27 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem.md @@ -0,0 +1,39 @@ +## metalctlv2 admin filesystem + +manage filesystem entities + +### Synopsis + +manage filesystem layouts which define how disks, raid arrays and volumes are set up on machines during installation + +### Options + +``` + -h, --help help for filesystem +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin](metalctlv2_admin.md) - admin commands +* [metalctlv2 admin filesystem apply](metalctlv2_admin_filesystem_apply.md) - applies one or more filesystems from a given file +* [metalctlv2 admin filesystem create](metalctlv2_admin_filesystem_create.md) - creates the filesystem +* [metalctlv2 admin filesystem delete](metalctlv2_admin_filesystem_delete.md) - deletes the filesystem +* [metalctlv2 admin filesystem describe](metalctlv2_admin_filesystem_describe.md) - describes the filesystem +* [metalctlv2 admin filesystem edit](metalctlv2_admin_filesystem_edit.md) - edit the filesystem through an editor and update +* [metalctlv2 admin filesystem list](metalctlv2_admin_filesystem_list.md) - list all filesystems +* [metalctlv2 admin filesystem match](metalctlv2_admin_filesystem_match.md) - matches a filesystem layout to a size and image or to a machine +* [metalctlv2 admin filesystem update](metalctlv2_admin_filesystem_update.md) - updates the filesystem + diff --git a/docs/admin/metalctlv2_admin_filesystem_apply.md b/docs/admin/metalctlv2_admin_filesystem_apply.md new file mode 100644 index 0000000..fc4b645 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_apply.md @@ -0,0 +1,46 @@ +## metalctlv2 admin filesystem apply + +applies one or more filesystems from a given file + +``` +metalctlv2 admin filesystem apply [flags] +``` + +### Options + +``` + --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. + -f, --file string filename of the create or update request in yaml format, or - for stdin. + + Example: + $ metalctlv2 filesystem describe filesystem-1 -o yaml > filesystem.yaml + $ vi filesystem.yaml + $ # either via stdin + $ cat filesystem.yaml | metalctlv2 filesystem apply -f - + $ # or via file + $ metalctlv2 filesystem apply -f filesystem.yaml + + the file can also contain multiple documents and perform a bulk operation. + + -h, --help help for apply + --skip-security-prompts skips security prompt for bulk operations + --timestamps when used with --file (bulk operation): prints timestamps in-between the operations +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_create.md b/docs/admin/metalctlv2_admin_filesystem_create.md new file mode 100644 index 0000000..7f451a3 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_create.md @@ -0,0 +1,46 @@ +## metalctlv2 admin filesystem create + +creates the filesystem + +``` +metalctlv2 admin filesystem create [flags] +``` + +### Options + +``` + --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. + -f, --file string filename of the create or update request in yaml format, or - for stdin. + + Example: + $ metalctlv2 filesystem describe filesystem-1 -o yaml > filesystem.yaml + $ vi filesystem.yaml + $ # either via stdin + $ cat filesystem.yaml | metalctlv2 filesystem create -f - + $ # or via file + $ metalctlv2 filesystem create -f filesystem.yaml + + the file can also contain multiple documents and perform a bulk operation. + + -h, --help help for create + --skip-security-prompts skips security prompt for bulk operations + --timestamps when used with --file (bulk operation): prints timestamps in-between the operations +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_delete.md b/docs/admin/metalctlv2_admin_filesystem_delete.md new file mode 100644 index 0000000..da89f53 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_delete.md @@ -0,0 +1,46 @@ +## metalctlv2 admin filesystem delete + +deletes the filesystem + +``` +metalctlv2 admin filesystem delete [flags] +``` + +### Options + +``` + --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. + -f, --file string filename of the create or update request in yaml format, or - for stdin. + + Example: + $ metalctlv2 filesystem describe filesystem-1 -o yaml > filesystem.yaml + $ vi filesystem.yaml + $ # either via stdin + $ cat filesystem.yaml | metalctlv2 filesystem delete -f - + $ # or via file + $ metalctlv2 filesystem delete -f filesystem.yaml + + the file can also contain multiple documents and perform a bulk operation. + + -h, --help help for delete + --skip-security-prompts skips security prompt for bulk operations + --timestamps when used with --file (bulk operation): prints timestamps in-between the operations +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_describe.md b/docs/admin/metalctlv2_admin_filesystem_describe.md new file mode 100644 index 0000000..f331aa9 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_describe.md @@ -0,0 +1,31 @@ +## metalctlv2 admin filesystem describe + +describes the filesystem + +``` +metalctlv2 admin filesystem describe [flags] +``` + +### Options + +``` + -h, --help help for describe +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_edit.md b/docs/admin/metalctlv2_admin_filesystem_edit.md new file mode 100644 index 0000000..0f5e807 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_edit.md @@ -0,0 +1,31 @@ +## metalctlv2 admin filesystem edit + +edit the filesystem through an editor and update + +``` +metalctlv2 admin filesystem edit [flags] +``` + +### Options + +``` + -h, --help help for edit +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_list.md b/docs/admin/metalctlv2_admin_filesystem_list.md new file mode 100644 index 0000000..552e4fc --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_list.md @@ -0,0 +1,33 @@ +## metalctlv2 admin filesystem list + +list all filesystems + +``` +metalctlv2 admin filesystem list [flags] +``` + +### Options + +``` + -h, --help help for list + --id string id of the filesystem layout to filter for + --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_match.md b/docs/admin/metalctlv2_admin_filesystem_match.md new file mode 100644 index 0000000..8530e1a --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_match.md @@ -0,0 +1,40 @@ +## metalctlv2 admin filesystem match + +matches a filesystem layout to a size and image or to a machine + +### Synopsis + +matches a filesystem layout either to a given size and image combination, +or checks whether a given filesystem layout matches a given machine. + +``` +metalctlv2 admin filesystem match [flags] +``` + +### Options + +``` + --filesystem-layout string id of the filesystem layout to check against a machine + -h, --help help for match + --image string machine image to match against a filesystem layout + --machine string uuid of the machine to check against a filesystem layout + --size string machine size to match against a filesystem layout +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/admin/metalctlv2_admin_filesystem_update.md b/docs/admin/metalctlv2_admin_filesystem_update.md new file mode 100644 index 0000000..92a8ba9 --- /dev/null +++ b/docs/admin/metalctlv2_admin_filesystem_update.md @@ -0,0 +1,46 @@ +## metalctlv2 admin filesystem update + +updates the filesystem + +``` +metalctlv2 admin filesystem update [flags] +``` + +### Options + +``` + --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row. + -f, --file string filename of the create or update request in yaml format, or - for stdin. + + Example: + $ metalctlv2 filesystem describe filesystem-1 -o yaml > filesystem.yaml + $ vi filesystem.yaml + $ # either via stdin + $ cat filesystem.yaml | metalctlv2 filesystem update -f - + $ # or via file + $ metalctlv2 filesystem update -f filesystem.yaml + + the file can also contain multiple documents and perform a bulk operation. + + -h, --help help for update + --skip-security-prompts skips security prompt for bulk operations + --timestamps when used with --file (bulk operation): prints timestamps in-between the operations +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 admin filesystem](metalctlv2_admin_filesystem.md) - manage filesystem entities + diff --git a/docs/metalctlv2_filesystem.md b/docs/metalctlv2_filesystem.md new file mode 100644 index 0000000..91624e2 --- /dev/null +++ b/docs/metalctlv2_filesystem.md @@ -0,0 +1,33 @@ +## metalctlv2 filesystem + +manage filesystem entities + +### Synopsis + +a filesystem layout defines how disks, raid arrays and volumes are set up on a machine during installation + +### Options + +``` + -h, --help help for filesystem +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2](metalctlv2.md) - cli for managing entities in metal-stack +* [metalctlv2 filesystem describe](metalctlv2_filesystem_describe.md) - describes the filesystem +* [metalctlv2 filesystem list](metalctlv2_filesystem_list.md) - list all filesystems + diff --git a/docs/metalctlv2_filesystem_describe.md b/docs/metalctlv2_filesystem_describe.md new file mode 100644 index 0000000..5ad91d7 --- /dev/null +++ b/docs/metalctlv2_filesystem_describe.md @@ -0,0 +1,31 @@ +## metalctlv2 filesystem describe + +describes the filesystem + +``` +metalctlv2 filesystem describe [flags] +``` + +### Options + +``` + -h, --help help for describe +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 filesystem](metalctlv2_filesystem.md) - manage filesystem entities + diff --git a/docs/metalctlv2_filesystem_list.md b/docs/metalctlv2_filesystem_list.md new file mode 100644 index 0000000..35a5a9d --- /dev/null +++ b/docs/metalctlv2_filesystem_list.md @@ -0,0 +1,33 @@ +## metalctlv2 filesystem list + +list all filesystems + +``` +metalctlv2 filesystem list [flags] +``` + +### Options + +``` + -h, --help help for list + --id string id of the filesystem layout which should be listed + --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name +``` + +### Options inherited from parent commands + +``` + --api-token string the token used for api requests + --api-url string the url to the metal-stack.io api + -c, --config string alternative config file path, (default is ~/.metal-stack/config.yaml) + --debug debug output + --force-color force colored output even without tty + -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table") + --template string output template for template output-format, go template format. For property names inspect the output of -o json or -o yaml for reference. + --timeout duration request timeout used for api requests +``` + +### SEE ALSO + +* [metalctlv2 filesystem](metalctlv2_filesystem.md) - manage filesystem entities + From 835788759c435fd53f052b1821c1972ab675bbe6 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Fri, 23 Oct 2026 11:20:33 +0200 Subject: [PATCH 5/5] Review Findings --- cmd/admin/v2/filesystem.go | 10 +++++----- tests/e2e/admin/filesystem_test.go | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/admin/v2/filesystem.go b/cmd/admin/v2/filesystem.go index da5d57d..6f13aec 100644 --- a/cmd/admin/v2/filesystem.go +++ b/cmd/admin/v2/filesystem.go @@ -52,12 +52,12 @@ or checks whether a given filesystem layout matches a given machine.`, matchCmd.Flags().String("size", "", "machine size to match against a filesystem layout") matchCmd.Flags().String("image", "", "machine image to match against a filesystem layout") matchCmd.Flags().String("machine", "", "uuid of the machine to check against a filesystem layout") - matchCmd.Flags().String("filesystem-layout", "", "id of the filesystem layout to check against a machine") + matchCmd.Flags().String("id", "", "id of the filesystem layout to check against a machine") genericcli.Must(matchCmd.RegisterFlagCompletionFunc("size", c.Completion.Size)) genericcli.Must(matchCmd.RegisterFlagCompletionFunc("image", c.Completion.Image)) genericcli.Must(matchCmd.RegisterFlagCompletionFunc("machine", c.Completion.Machine)) - genericcli.Must(matchCmd.RegisterFlagCompletionFunc("filesystem-layout", c.Completion.FilesystemLayout)) + genericcli.Must(matchCmd.RegisterFlagCompletionFunc("id", c.Completion.FilesystemLayout)) return genericcli.NewCmds(cmdsConfig, matchCmd) } @@ -157,7 +157,7 @@ func (w *filesystem) match(_ *cobra.Command) error { sizeSet = viper.IsSet("size") imageSet = viper.IsSet("image") machineSet = viper.IsSet("machine") - layoutSet = viper.IsSet("filesystem-layout") + layoutSet = viper.IsSet("id") req *adminv2.FilesystemServiceMatchRequest ) @@ -176,12 +176,12 @@ func (w *filesystem) match(_ *cobra.Command) error { Match: &adminv2.FilesystemServiceMatchRequest_MachineAndFilesystemlayout{ MachineAndFilesystemlayout: &adminv2.MatchMachineAndFilesystemLayout{ Machine: viper.GetString("machine"), - FilesystemLayout: viper.GetString("filesystem-layout"), + FilesystemLayout: viper.GetString("id"), }, }, } default: - return fmt.Errorf("either both --size and --image or both --machine and --filesystem-layout must be set") + return fmt.Errorf("either both --size and --image or both --machine and --id must be set") } ctx, cancel := w.c.NewRequestContext() diff --git a/tests/e2e/admin/filesystem_test.go b/tests/e2e/admin/filesystem_test.go index 89790b2..f75a35c 100644 --- a/tests/e2e/admin/filesystem_test.go +++ b/tests/e2e/admin/filesystem_test.go @@ -310,7 +310,7 @@ func Test_AdminFileSystemCmd_Match_MachineAndLayout(t *testing.T) { tests := []*e2e.Test[adminv2.FilesystemServiceMatchResponse, *apiv2.FilesystemLayout]{ { Name: "match machine and filesystem layout", - CmdArgs: []string{"admin", "filesystem", "match", "--machine", machineUUID, "--filesystem-layout", testresources.FilesystemLayout1().Id}, + CmdArgs: []string{"admin", "filesystem", "match", "--machine", machineUUID, "--id", testresources.FilesystemLayout1().Id}, NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{ ClientCalls: []client.ClientCall{ { @@ -360,13 +360,13 @@ func Test_AdminFileSystemCmd_Match_InvalidFlags(t *testing.T) { Name: "match without flags fails", CmdArgs: []string{"admin", "filesystem", "match"}, NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{}), - WantErr: fmt.Errorf("either both --size and --image or both --machine and --filesystem-layout must be set"), + WantErr: fmt.Errorf("either both --size and --image or both --machine and --id must be set"), }, { Name: "match with only size fails", CmdArgs: []string{"admin", "filesystem", "match", "--size", "m2.small"}, NewRootCmd: e2erootcmd.NewRootCmd(t, &e2erootcmd.TestConfig{}), - WantErr: fmt.Errorf("either both --size and --image or both --machine and --filesystem-layout must be set"), + WantErr: fmt.Errorf("either both --size and --image or both --machine and --id must be set"), }, } for _, tt := range tests {