Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/reference/manual/hcloud.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ A command-line interface for Hetzner Cloud
* [hcloud server](hcloud_server.md) - Manage Servers
* [hcloud server-type](hcloud_server-type.md) - View Server Types
* [hcloud ssh-key](hcloud_ssh-key.md) - Manage SSH Keys
* [hcloud storage-box-type](hcloud_storage-box-type.md) - View Storage Box Types
* [hcloud version](hcloud_version.md) - Print version information
* [hcloud volume](hcloud_volume.md) - Manage Volumes
28 changes: 28 additions & 0 deletions docs/reference/manual/hcloud_storage-box-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## hcloud storage-box-type

View Storage Box Types

### Options

```
-h, --help help for storage-box-type
```

### Options inherited from parent commands

```
--config string Config file path (default "~/.config/hcloud/cli.toml")
--context string Currently active context
--debug Enable debug output
--debug-file string File to write debug output to
--endpoint string Hetzner Cloud API endpoint (default "https://api.hetzner.cloud/v1")
--hetzner-endpoint string Hetzner API endpoint (default "https://api.hetzner.com/v1")
--poll-interval duration Interval at which to poll information, for example action progress (default 500ms)
--quiet If true, only print error messages
```

### SEE ALSO

* [hcloud](hcloud.md) - Hetzner Cloud CLI
* [hcloud storage-box-type describe](hcloud_storage-box-type_describe.md) - Describe a Storage Box Type
* [hcloud storage-box-type list](hcloud_storage-box-type_list.md) - List Storage Box Types
31 changes: 31 additions & 0 deletions docs/reference/manual/hcloud_storage-box-type_describe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## hcloud storage-box-type describe

Describe a Storage Box Type

```
hcloud storage-box-type describe [options] <storage-box-type>
```

### Options

```
-h, --help help for describe
-o, --output stringArray output options: json|yaml|format
```

### Options inherited from parent commands

```
--config string Config file path (default "~/.config/hcloud/cli.toml")
--context string Currently active context
--debug Enable debug output
--debug-file string File to write debug output to
--endpoint string Hetzner Cloud API endpoint (default "https://api.hetzner.cloud/v1")
--hetzner-endpoint string Hetzner API endpoint (default "https://api.hetzner.com/v1")
--poll-interval duration Interval at which to poll information, for example action progress (default 500ms)
--quiet If true, only print error messages
```

### SEE ALSO

* [hcloud storage-box-type](hcloud_storage-box-type.md) - View Storage Box Types
51 changes: 51 additions & 0 deletions docs/reference/manual/hcloud_storage-box-type_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## hcloud storage-box-type list

List Storage Box Types

### Synopsis

Displays a list of Storage Box Types.

Output can be controlled with the -o flag. Use -o noheader to suppress the
table header. Displayed columns and their order can be set with
-o columns=automatic_snapshot_limit,deprecated (see available columns below).

Columns:
- automatic_snapshot_limit
- deprecated
- description
- id
- name
- size
- snapshot_limit
- subaccounts_limit

```
hcloud storage-box-type list [options]
```

### Options

```
-h, --help help for list
-o, --output stringArray output options: noheader|columns=...|json|yaml
-l, --selector string Selector to filter by labels
-s, --sort strings Determine the sorting of the result
```

### Options inherited from parent commands

```
--config string Config file path (default "~/.config/hcloud/cli.toml")
--context string Currently active context
--debug Enable debug output
--debug-file string File to write debug output to
--endpoint string Hetzner Cloud API endpoint (default "https://api.hetzner.cloud/v1")
--hetzner-endpoint string Hetzner API endpoint (default "https://api.hetzner.com/v1")
--poll-interval duration Interval at which to poll information, for example action progress (default 500ms)
--quiet If true, only print error messages
```

### SEE ALSO

* [hcloud storage-box-type](hcloud_storage-box-type.md) - View Storage Box Types
22 changes: 11 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ require (
github.com/stretchr/testify v1.10.0
github.com/swaggest/assertjson v1.9.0
go.uber.org/mock v0.5.2
golang.org/x/crypto v0.40.0
golang.org/x/term v0.33.0
golang.org/x/text v0.27.0
golang.org/x/crypto v0.41.0
golang.org/x/term v0.34.0
golang.org/x/text v0.28.0
)

require (
Expand All @@ -44,10 +44,10 @@ require (
github.com/nxadm/tail v1.4.11 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/client_golang v1.23.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
Expand All @@ -59,10 +59,10 @@ require (
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/sys v0.34.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/sys v0.35.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/hetznercloud/hcloud-go/v2 => github.com/hetznercloud/hcloud-go/v2 v2.22.1-0.20250806091721-81a5117fcc04
replace github.com/hetznercloud/hcloud-go/v2 => github.com/hetznercloud/hcloud-go/v2 v2.22.1-0.20250820083549-f707a58dc9c7
46 changes: 24 additions & 22 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ 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/guptarohit/asciigraph v0.7.3 h1:p05XDDn7cBTWiBqWb30mrwxd6oU0claAjqeytllnsPY=
github.com/guptarohit/asciigraph v0.7.3/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
github.com/hetznercloud/hcloud-go/v2 v2.22.1-0.20250806091721-81a5117fcc04 h1:GvCyd/5JQkJMMGMINJ2gexP4wOFfk32ko2zqS/ZKwYE=
github.com/hetznercloud/hcloud-go/v2 v2.22.1-0.20250806091721-81a5117fcc04/go.mod h1:t14Logj+iLXyS03DGwEyrN+y7/C9243CJt3IArTHbyM=
github.com/hetznercloud/hcloud-go/v2 v2.22.1-0.20250820083549-f707a58dc9c7 h1:AOBZLlJx/SCV60Jp5AGu5HIS+5qdBPcjL8ne+st+G/0=
github.com/hetznercloud/hcloud-go/v2 v2.22.1-0.20250820083549-f707a58dc9c7/go.mod h1:rDpBO6bbG1aP6wcScPCOx880e7EB4uRxDYhQ/+qE/+w=
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
Expand Down Expand Up @@ -75,14 +75,14 @@ github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xl
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
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.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
Expand Down Expand Up @@ -124,24 +124,26 @@ github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcm
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
Expand Down
2 changes: 2 additions & 0 deletions internal/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/hetznercloud/cli/internal/cmd/server"
"github.com/hetznercloud/cli/internal/cmd/servertype"
"github.com/hetznercloud/cli/internal/cmd/sshkey"
"github.com/hetznercloud/cli/internal/cmd/storageboxtype"
"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/cmd/version"
"github.com/hetznercloud/cli/internal/cmd/volume"
Expand Down Expand Up @@ -60,6 +61,7 @@ func NewRootCommand(s state.State) *cobra.Command {
firewall.NewCommand(s),
placementgroup.NewCommand(s),
primaryip.NewCommand(s),
storageboxtype.NewCommand(s),
)

cmd.AddCommand(
Expand Down
71 changes: 71 additions & 0 deletions internal/cmd/storageboxtype/describe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package storageboxtype

import (
"github.com/dustin/go-humanize"
"github.com/spf13/cobra"

"github.com/hetznercloud/cli/internal/cmd/base"
"github.com/hetznercloud/cli/internal/cmd/util"
"github.com/hetznercloud/cli/internal/hcapi2"
"github.com/hetznercloud/cli/internal/state"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)

var DescribeCmd = base.DescribeCmd[*hcloud.StorageBoxType]{
ResourceNameSingular: "Storage Box Type",
ShortDescription: "Describe a Storage Box Type",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.StorageBoxType().Names },
Fetch: func(s state.State, _ *cobra.Command, idOrName string) (*hcloud.StorageBoxType, any, error) {
st, _, err := s.Client().StorageBoxType().Get(s, idOrName)
if err != nil {
return nil, nil, err
}
return st, hcloud.SchemaFromStorageBoxType(st), nil
},
PrintText: func(s state.State, cmd *cobra.Command, storageBoxType *hcloud.StorageBoxType) error {
cmd.Printf("ID:\t\t\t\t%d\n", storageBoxType.ID)
cmd.Printf("Name:\t\t\t\t%s\n", storageBoxType.Name)
cmd.Printf("Description:\t\t\t%s\n", storageBoxType.Description)
cmd.Printf("Size:\t\t\t\t%s\n", humanize.IBytes(uint64(storageBoxType.Size)))
cmd.Printf("Snapshot Limit:\t\t\t%d\n", storageBoxType.SnapshotLimit)
cmd.Printf("Automatic Snapshot Limit:\t%d\n", storageBoxType.AutomaticSnapshotLimit)
cmd.Printf("Subaccounts Limit:\t\t%d\n", storageBoxType.SubaccountsLimit)
cmd.Print(util.DescribeDeprecation(storageBoxType))

err := loadCurrencyFromAPI(s, storageBoxType)
if err != nil {
cmd.PrintErrf("failed to get currency for Storage Box Type prices: %v", err)
}

cmd.Printf("Pricings per Location:\n")
for _, price := range storageBoxType.Pricings {
cmd.Printf(" - Location:\t%s\n", price.Location)
cmd.Printf(" Hourly:\t%s\n", util.GrossPrice(price.PriceHourly))
cmd.Printf(" Monthly:\t%s\n", util.GrossPrice(price.PriceMonthly))
cmd.Printf(" Setup Fee:\t%s\n", util.GrossPrice(price.SetupFee))
cmd.Printf("\n")
}

return nil
},
}

func loadCurrencyFromAPI(s state.State, storageBoxType *hcloud.StorageBoxType) error {
pricing, _, err := s.Client().Pricing().Get(s)
if err != nil {
return err
}

for i := range storageBoxType.Pricings {
storageBoxType.Pricings[i].PriceMonthly.Currency = pricing.Currency
storageBoxType.Pricings[i].PriceMonthly.VATRate = pricing.VATRate

storageBoxType.Pricings[i].PriceHourly.Currency = pricing.Currency
storageBoxType.Pricings[i].PriceHourly.VATRate = pricing.VATRate

storageBoxType.Pricings[i].SetupFee.Currency = pricing.Currency
storageBoxType.Pricings[i].SetupFee.VATRate = pricing.VATRate
}

return nil
}
Loading