From 753bb948b152aa0b9d37b1f2bd92e998493e5052 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Mon, 24 Aug 2026 07:58:01 +0200 Subject: [PATCH 1/2] Sort components and update to go-1.27 --- .github/workflows/docker.yaml | 10 ++-- cmd/admin/v2/component.go | 2 + cmd/admin/v2/image.go | 30 +++++----- cmd/admin/v2/token.go | 44 +++++++-------- cmd/api/v2/project.go | 16 +++--- cmd/api/v2/token.go | 32 +++++------ cmd/sorters/component.go | 20 +++++++ docs/admin/metalctlv2_admin_component_list.md | 1 + go.mod | 26 ++++----- go.sum | 56 +++++++++---------- 10 files changed, 130 insertions(+), 107 deletions(-) create mode 100644 cmd/sorters/component.go diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 719f700..ea661e5 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -45,10 +45,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Setup Go - uses: actions/setup-go@v6 + uses: actions/setup-go@v7 with: go-version-file: 'go.mod' @@ -67,7 +67,7 @@ jobs: make cli GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} - name: Log in to the container registry - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.DOCKER_REGISTRY_USER }} @@ -75,11 +75,11 @@ jobs: if: ${{ matrix.os == 'linux' && matrix.arch == 'amd64' }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 if: ${{ matrix.os == 'linux' && matrix.arch == 'amd64' }} - name: Build and push image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . push: true diff --git a/cmd/admin/v2/component.go b/cmd/admin/v2/component.go index e731c59..cd0d836 100644 --- a/cmd/admin/v2/component.go +++ b/cmd/admin/v2/component.go @@ -8,6 +8,7 @@ import ( 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/metal-lib/pkg/genericcli" "github.com/metal-stack/metal-lib/pkg/genericcli/printers" "github.com/metal-stack/metal-lib/pkg/pointer" @@ -32,6 +33,7 @@ func newComponentCmd(c *config.Config) *cobra.Command { Description: "list status of components, e.g. microservices connected to the metal-apiserver", DescribePrinter: func() printers.Printer { return c.DescribePrinter }, ListPrinter: func() printers.Printer { return c.ListPrinter }, + Sorter: sorters.ComponentSorter(), OnlyCmds: genericcli.OnlyCmds(genericcli.DescribeCmd, genericcli.ListCmd, genericcli.DeleteCmd), ListCmdMutateFn: func(cmd *cobra.Command) { cmd.Flags().String("uuid", "", "lists only component with this uuid") diff --git a/cmd/admin/v2/image.go b/cmd/admin/v2/image.go index e405026..72e2487 100644 --- a/cmd/admin/v2/image.go +++ b/cmd/admin/v2/image.go @@ -214,27 +214,27 @@ func (c *image) List() ([]*apiv2.Image, error) { func (c *image) Convert(r *apiv2.Image) (string, *adminv2.ImageServiceCreateRequest, *adminv2.ImageServiceUpdateRequest, error) { return r.Id, &adminv2.ImageServiceCreateRequest{ - Image: &apiv2.Image{ - Id: r.Id, - Url: r.Url, - Name: r.Name, - Description: r.Description, - Features: r.Features, - Meta: r.Meta, - Classification: r.Classification, - ExpiresAt: r.ExpiresAt, - }, - }, &adminv2.ImageServiceUpdateRequest{ - UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), - Labels: helpers.UpdateLabelsFromMeta(r.Meta), + Image: &apiv2.Image{ Id: r.Id, - Url: &r.Url, + Url: r.Url, Name: r.Name, Description: r.Description, Features: r.Features, + Meta: r.Meta, Classification: r.Classification, ExpiresAt: r.ExpiresAt, - }, nil + }, + }, &adminv2.ImageServiceUpdateRequest{ + UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), + Labels: helpers.UpdateLabelsFromMeta(r.Meta), + Id: r.Id, + Url: &r.Url, + Name: r.Name, + Description: r.Description, + Features: r.Features, + Classification: r.Classification, + ExpiresAt: r.ExpiresAt, + }, nil } func (c *image) Update(rq *adminv2.ImageServiceUpdateRequest) (*apiv2.Image, error) { diff --git a/cmd/admin/v2/token.go b/cmd/admin/v2/token.go index 183dbcf..4e26b3c 100644 --- a/cmd/admin/v2/token.go +++ b/cmd/admin/v2/token.go @@ -228,31 +228,31 @@ func (t *token) Convert(r *apiv2.Token) (string, *adminv2.TokenServiceCreateRequ } return r.Uuid, &adminv2.TokenServiceCreateRequest{ - User: &r.User, - TokenCreateRequest: &apiv2.TokenServiceCreateRequest{ - Description: r.GetDescription(), - Permissions: perms, - ProjectRoles: r.GetProjectRoles(), - TenantRoles: r.GetTenantRoles(), - Expires: durationpb.New(time.Until(r.GetExpires().AsTime())), - Labels: pointer.SafeDeref(r.Meta).Labels, - }, - }, &apiv2.TokenServiceUpdateRequest{ - Uuid: r.Uuid, - Description: pointer.PointerOrNil(r.Description), + User: &r.User, + TokenCreateRequest: &apiv2.TokenServiceCreateRequest{ + Description: r.GetDescription(), Permissions: perms, - ProjectRoles: r.ProjectRoles, - TenantRoles: r.TenantRoles, - AdminRole: r.AdminRole, - Labels: &apiv2.UpdateLabels{ - Strategy: &apiv2.UpdateLabels_Replace{ - Replace: &apiv2.Labels{ - Labels: pointer.SafeDeref(pointer.SafeDeref(r.Meta).Labels).Labels, - }, + ProjectRoles: r.GetProjectRoles(), + TenantRoles: r.GetTenantRoles(), + Expires: durationpb.New(time.Until(r.GetExpires().AsTime())), + Labels: pointer.SafeDeref(r.Meta).Labels, + }, + }, &apiv2.TokenServiceUpdateRequest{ + Uuid: r.Uuid, + Description: pointer.PointerOrNil(r.Description), + Permissions: perms, + ProjectRoles: r.ProjectRoles, + TenantRoles: r.TenantRoles, + AdminRole: r.AdminRole, + Labels: &apiv2.UpdateLabels{ + Strategy: &apiv2.UpdateLabels_Replace{ + Replace: &apiv2.Labels{ + Labels: pointer.SafeDeref(pointer.SafeDeref(r.Meta).Labels).Labels, }, }, - UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), - }, nil + }, + UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), + }, nil } func (t *token) Update(rq *apiv2.TokenServiceUpdateRequest) (*apiv2.Token, error) { diff --git a/cmd/api/v2/project.go b/cmd/api/v2/project.go index 6c14735..2f4f398 100644 --- a/cmd/api/v2/project.go +++ b/cmd/api/v2/project.go @@ -242,14 +242,14 @@ func (c *project) Delete(id string) (*apiv2.Project, error) { func (c *project) Convert(r *apiv2.Project) (string, *apiv2.ProjectServiceCreateRequest, *apiv2.ProjectServiceUpdateRequest, error) { return r.Uuid, &apiv2.ProjectServiceCreateRequest{ - Login: r.Tenant, - Name: r.Name, - Description: r.Description, - }, &apiv2.ProjectServiceUpdateRequest{ - Project: r.Uuid, - Name: new(r.Name), - Description: new(r.Description), - }, nil + Login: r.Tenant, + Name: r.Name, + Description: r.Description, + }, &apiv2.ProjectServiceUpdateRequest{ + Project: r.Uuid, + Name: new(r.Name), + Description: new(r.Description), + }, nil } func (c *project) Update(rq *apiv2.ProjectServiceUpdateRequest) (*apiv2.Project, error) { diff --git a/cmd/api/v2/token.go b/cmd/api/v2/token.go index 8e70ba7..25189d4 100644 --- a/cmd/api/v2/token.go +++ b/cmd/api/v2/token.go @@ -185,20 +185,20 @@ func (c *token) Convert(r *apiv2.Token) (string, *apiv2.TokenServiceCreateReques } return r.Uuid, &apiv2.TokenServiceCreateRequest{ - Description: r.GetDescription(), - Permissions: perms, - ProjectRoles: r.GetProjectRoles(), - TenantRoles: r.GetTenantRoles(), - Expires: durationpb.New(time.Until(r.GetExpires().AsTime())), - Labels: pointer.SafeDeref(r.Meta).Labels, - }, &apiv2.TokenServiceUpdateRequest{ - Uuid: r.Uuid, - Description: pointer.PointerOrNil(r.Description), - Permissions: perms, - ProjectRoles: r.ProjectRoles, - TenantRoles: r.TenantRoles, - AdminRole: r.AdminRole, - Labels: helpers.UpdateLabelsFromMeta(r.Meta), - UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), - }, nil + Description: r.GetDescription(), + Permissions: perms, + ProjectRoles: r.GetProjectRoles(), + TenantRoles: r.GetTenantRoles(), + Expires: durationpb.New(time.Until(r.GetExpires().AsTime())), + Labels: pointer.SafeDeref(r.Meta).Labels, + }, &apiv2.TokenServiceUpdateRequest{ + Uuid: r.Uuid, + Description: pointer.PointerOrNil(r.Description), + Permissions: perms, + ProjectRoles: r.ProjectRoles, + TenantRoles: r.TenantRoles, + AdminRole: r.AdminRole, + Labels: helpers.UpdateLabelsFromMeta(r.Meta), + UpdateMeta: helpers.UpdateMetaFromMeta(r.Meta), + }, nil } diff --git a/cmd/sorters/component.go b/cmd/sorters/component.go new file mode 100644 index 0000000..e96873a --- /dev/null +++ b/cmd/sorters/component.go @@ -0,0 +1,20 @@ +package sorters + +import ( + apiv2 "github.com/metal-stack/api/go/metalstack/api/v2" + "github.com/metal-stack/metal-lib/pkg/multisort" +) + +func ComponentSorter() *multisort.Sorter[*apiv2.Component] { + return multisort.New(multisort.FieldMap[*apiv2.Component]{ + "type": func(a, b *apiv2.Component, descending bool) multisort.CompareResult { + return multisort.Compare(a.Type, b.Type, descending) + }, + "identifier": func(a, b *apiv2.Component, descending bool) multisort.CompareResult { + return multisort.Compare(a.Identifier, b.Identifier, descending) + }, + "started": func(a, b *apiv2.Component, descending bool) multisort.CompareResult { + return multisort.Compare(a.StartedAt.AsTime().String(), b.StartedAt.AsTime().String(), descending) + }, + }, multisort.Keys{{ID: "type", Descending: true}, {ID: "identifier", Descending: true}}) +} diff --git a/docs/admin/metalctlv2_admin_component_list.md b/docs/admin/metalctlv2_admin_component_list.md index 268c020..197f61c 100644 --- a/docs/admin/metalctlv2_admin_component_list.md +++ b/docs/admin/metalctlv2_admin_component_list.md @@ -11,6 +11,7 @@ metalctlv2 admin component list [flags] ``` -h, --help help for list --identifier string lists only component with this identifier + --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: identifier|started|type --type string lists only component of this type --uuid string lists only component with this uuid ``` diff --git a/go.mod b/go.mod index b6beb7d..c168f70 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/metal-stack/cli -go 1.26.5 +go 1.27 require ( connectrpc.com/connect v1.20.0 @@ -9,14 +9,14 @@ require ( 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.5.0 + github.com/metal-stack/api v0.5.1 github.com/metal-stack/metal-lib v0.26.3 github.com/metal-stack/v v1.0.3 github.com/spf13/afero v1.15.0 github.com/spf13/cobra v1.10.2 github.com/spf13/viper v1.21.0 - github.com/stretchr/testify v1.12.0 - google.golang.org/grpc v1.83.0 + github.com/stretchr/testify v1.12.1 + google.golang.org/grpc v1.83.1 google.golang.org/protobuf v1.36.12 sigs.k8s.io/yaml v1.6.0 ) @@ -36,12 +36,12 @@ require ( github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/coder/websocket v1.8.15 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect - github.com/creachadair/msync v0.10.0 // indirect + 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.2 // indirect + github.com/fxamacker/cbor/v2 v2.9.3 // indirect github.com/gaissmai/bart v0.29.0 // indirect - github.com/go-json-experiment/json v0.0.0-20260623181947-01eb4420fa68 // 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.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect @@ -61,7 +61,7 @@ require ( github.com/klauspost/connect-compress/v2 v2.1.1 // indirect github.com/mattn/go-colorable v0.1.15 // indirect github.com/mattn/go-isatty v0.0.24 // indirect - github.com/mattn/go-runewidth v0.0.27 // indirect + github.com/mattn/go-runewidth v0.0.28 // 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 @@ -92,7 +92,7 @@ require ( go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/crypto v0.55.0 // indirect - golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297 // indirect + golang.org/x/exp v0.0.0-20260820142414-ca536658362e // 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 @@ -102,12 +102,12 @@ require ( golang.org/x/time v0.15.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-20260810153831-ec0a7760b754 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260810153831-ec0a7760b754 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // 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.3 // indirect + k8s.io/apimachinery v0.36.4 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect - tailscale.com v1.102.2 // indirect + tailscale.com v1.102.3 // indirect ) diff --git a/go.sum b/go.sum index 52f203c..5bc7900 100644 --- a/go.sum +++ b/go.sum @@ -77,10 +77,10 @@ github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8 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.2 h1:cOP0xkfYkk4mxqPl4SmjnrY+agrpgiEqsVygLnPvJto= -github.com/creachadair/mds v0.30.2/go.mod h1:dMBTCSy3iS3dwh4Rb1zxeZz2d7K8+N24GCTsayWtQRI= -github.com/creachadair/msync v0.10.0 h1:2RlGs187RQN5tzyluKEkbkXq+LRK2KIR+An6FoB9x+M= -github.com/creachadair/msync v0.10.0/go.mod h1:J+4p7as+O7NWydXYGJNrigY67qj1F1GB0CcTWyV/5AE= +github.com/creachadair/mds v0.30.5 h1:JtylThbC3wUndriq7yZiY23AD0L7ZaKSvx3XQwQk8FI= +github.com/creachadair/mds v0.30.5/go.mod h1:NGUd6kGUG0qQd2kgGOqb8NzakLnSmWZ5be2pHZsrBN4= +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/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= @@ -101,14 +101,14 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk 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.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= -github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +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/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-20260623181947-01eb4420fa68 h1:KZaTBSyshWX3MP5jukJcNSuXDQTO+rNpt0J564dX/eg= -github.com/go-json-experiment/json v0.0.0-20260623181947-01eb4420fa68/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg= +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= @@ -181,8 +181,8 @@ github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy github.com/mattn/go-colorable v0.1.15/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.27 h1:Feg/Oou5zI/wnpgDF6omIU0OokC9GxLC/WRknhVlIR0= -github.com/mattn/go-runewidth v0.0.27/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8= +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/mdlayher/netlink v1.11.2 h1:HKh2jqe+omdSWcQ88nrT7INE61B0NXfiSPFdgL4YbNI= @@ -191,8 +191,8 @@ github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ 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.5.0 h1:AtQUo2s4UjVCVXyOJQDxDaQnDmyzsS/TRTHe75nhibs= -github.com/metal-stack/api v0.5.0/go.mod h1:QbDG4YRFIkDf1z6cGmeu0m/791IAMyk8/9U/lsrxH8E= +github.com/metal-stack/api v0.5.1 h1:cA4i56RYXwcda/EkEWb2MG/YGQAEqJ4RvwxS7RtdUaA= +github.com/metal-stack/api v0.5.1/go.mod h1:QbDG4YRFIkDf1z6cGmeu0m/791IAMyk8/9U/lsrxH8E= 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/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= @@ -253,8 +253,8 @@ 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/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI= -github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw= +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= github.com/studio-b12/gowebdav v0.13.0/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -302,8 +302,8 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= -golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297 h1:YXnL44eJ77R+ji4/ooy8UsXIhz+lbi2Qgdlc8iRN0gY= -golang.org/x/exp v0.0.0-20260813180055-c1d0aacb2297/go.mod h1:Mkmymgv+uMpSQ/XxJ/7GpdrdYoqm3u72jEbpCLiJmNk= +golang.org/x/exp v0.0.0-20260820142414-ca536658362e h1:01Ju2A/fZKkci4zqx0eZxw//DnRYOnBiGJG14hFBhO8= +golang.org/x/exp v0.0.0-20260820142414-ca536658362e/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= @@ -333,12 +333,12 @@ golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446 h1:cqHQ3AycTHvM2R7 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-20260810153831-ec0a7760b754 h1:dWeMvEJ3JhYgqSCAHUZZJgMUyfniiiCvDc72x5EqJP0= -google.golang.org/genproto/googleapis/api v0.0.0-20260810153831-ec0a7760b754/go.mod h1:q/3oV3jAi5vwelxsVAprMBC8BcM2zmNe+IjRGd+9/ks= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260810153831-ec0a7760b754 h1:k5CJw9e5ONCcA/u0webKt092npXuY+KeGh3Q8NAVf0g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260810153831-ec0a7760b754/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ= -google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 h1:ax2KzoSRIZU/M0cIxri3pKxy99vniH1PVxWC6si/eZI= +google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688/go.mod h1:1RJ9BQGyNdZwkGc1eTqkErfRZ6RJyYPHZo73BZ1vQqI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA= +google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y= +google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= 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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -350,17 +350,17 @@ 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= -honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU= -honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc= +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.3 h1:PkzMRBRG8joFD8EhCuQAtNPvJlxb82FwplP26HIzvAM= -k8s.io/apimachinery v0.36.3/go.mod h1:cTSjBWgPe/6CQyBKzY/hDIRWCQQQeK0mfLbml0UYFHE= +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= 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.2 h1:K0TJMOFv0F9aJDSjM/C2uVtrwnLn+ek22c42x61FXeA= -tailscale.com v1.102.2/go.mod h1:ynxKzc9hDxwGLHORQE0qrTH1b8NBRrIsXcnfnug/3dg= +tailscale.com v1.102.3 h1:M1czCAtMuIcg+2Z+FBPbJyAk3ZEQGEFKnvHthtE1c6M= +tailscale.com v1.102.3/go.mod h1:47bv91Xbg4K1p5wti7F1dmKvUVWV5BXF78d9EWJ+d6c= From 3f05107b8a7b19934010fbe9ca90bc9a47a78ee1 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Mon, 24 Aug 2026 10:02:41 +0200 Subject: [PATCH 2/2] Sort by expiration --- cmd/sorters/component.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/sorters/component.go b/cmd/sorters/component.go index e96873a..d71e75d 100644 --- a/cmd/sorters/component.go +++ b/cmd/sorters/component.go @@ -16,5 +16,8 @@ func ComponentSorter() *multisort.Sorter[*apiv2.Component] { "started": func(a, b *apiv2.Component, descending bool) multisort.CompareResult { return multisort.Compare(a.StartedAt.AsTime().String(), b.StartedAt.AsTime().String(), descending) }, + "expiration": func(a, b *apiv2.Component, descending bool) multisort.CompareResult { + return multisort.Compare(a.Token.Expires.String(), b.Token.Expires.String(), descending) + }, }, multisort.Keys{{ID: "type", Descending: true}, {ID: "identifier", Descending: true}}) }