-
Notifications
You must be signed in to change notification settings - Fork 95
Open
Description
TL;DR
It would be great, if I could see which server-types are available in which datacenter.
I once wrote that - see below.
Are you interested in adding something like that the hcloud cli?
Example output:
❯ go run ./hcloud-server-types per-datacenter per-type
cax11: hel1-dc2 nbg1-dc3
cax21: hel1-dc2 nbg1-dc3
cax31: hel1-dc2 nbg1-dc3
cax41: hel1-dc2 nbg1-dc3
ccx13: ash-dc1 hel1-dc2 hil-dc1 nbg1-dc3 sin-dc1
ccx23: ash-dc1 hel1-dc2 hil-dc1 nbg1-dc3 sin-dc1
ccx33: ash-dc1 hel1-dc2 hil-dc1 nbg1-dc3 sin-dc1
ccx43: ash-dc1 hel1-dc2 hil-dc1 nbg1-dc3 sin-dc1
ccx53: ash-dc1 hel1-dc2 hil-dc1 nbg1-dc3 sin-dc1
ccx63: ash-dc1 hel1-dc2 hil-dc1 nbg1-dc3 sin-dc1
cpx11: ash-dc1 hil-dc1
cpx12: sin-dc1
cpx21: ash-dc1 hil-dc1
cpx22: hel1-dc2 nbg1-dc3 sin-dc1
cpx31: ash-dc1 hil-dc1
cpx32: hel1-dc2 nbg1-dc3 sin-dc1
cpx41: ash-dc1 hil-dc1
cpx42: hel1-dc2 nbg1-dc3 sin-dc1
cpx51: ash-dc1 hil-dc1
cpx52: hel1-dc2 nbg1-dc3 sin-dc1
cpx62: hel1-dc2 nbg1-dc3 sin-dc1
cx23: nbg1-dc3
cx33: nbg1-dc3
cx43: nbg1-dc3❯ go run ./hcloud-server-types per-datacenter
ash-dc1: ccx13 ccx23 ccx33 ccx43 ccx53 ccx63 cpx11 cpx21 cpx31 cpx41 cpx51
hel1-dc2: cax11 cax21 cax31 cax41 ccx13 ccx23 ccx33 ccx43 ccx53 ccx63 cpx22 cpx32 cpx42 cpx52 cpx62
hil-dc1: ccx13 ccx23 ccx33 ccx43 ccx53 ccx63 cpx11 cpx21 cpx31 cpx41 cpx51
nbg1-dc3: cax11 cax21 cax31 cax41 ccx13 ccx23 ccx33 ccx43 ccx53 ccx63 cpx22 cpx32 cpx42 cpx52 cpx62 cx23 cx33 cx43
sin-dc1: ccx13 ccx23 ccx33 ccx43 ccx53 ccx63 cpx12 cpx22 cpx32 cpx42 cpx52 cpx62
Example Code
// package main initializes hcloud-server-types.
package main
import (
"context"
"fmt"
"maps"
"os"
"slices"
"strings"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)
func usage() {
fmt.Printf(`Usage: %s [list | per-datacenter | per-type ]
List available HCloud server types. You can return a list, or server types per datacenter,
or datacenters per server type
`, os.Args[0])
}
func main() {
if len(os.Args) != 2 {
usage()
os.Exit(1)
}
command := os.Args[1]
if !slices.Contains([]string{"list", "per-datacenter", "per-type"}, command) {
fmt.Println("Invalid command. Use 'list', 'per-datacenter', or 'per-type'.")
usage()
os.Exit(1)
}
datacenterToTypes, err := getDatacenterToTypes()
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
}
switch command {
case "list":
datacenters := maps.Keys(datacenterToTypes)
for _, loc := range slices.Sorted(datacenters) {
types := datacenterToTypes[loc]
slices.Sort(types)
for _, serverType := range types {
fmt.Printf("%s: %s\n", loc, serverType)
}
}
return
case "per-datacenter":
datacenters := maps.Keys(datacenterToTypes)
for _, loc := range slices.Sorted(datacenters) {
types := datacenterToTypes[loc]
slices.Sort(types)
fmt.Printf("%s: %s\n", loc, strings.Join(types, " "))
}
return
case "per-type":
typesToDatacenters := make(map[string][]string)
for datacenter, types := range datacenterToTypes {
for _, serverType := range types {
typesToDatacenters[serverType] = append(typesToDatacenters[serverType], datacenter)
}
}
types := maps.Keys(typesToDatacenters)
for _, t := range slices.Sorted(types) {
datacenters := typesToDatacenters[t]
slices.Sort(datacenters)
fmt.Printf("%s: %s\n", t, strings.Join(datacenters, " "))
}
default:
panic("unknown command: " + command)
}
}
func getDatacenterToTypes() (map[string][]string, error) {
token := os.Getenv("HCLOUD_TOKEN")
if token == "" {
return nil, fmt.Errorf("HCLOUD_TOKEN environment variable is not set")
}
client := hcloud.NewClient(
hcloud.WithToken(token),
)
ctx := context.Background()
serverTypes, err := client.ServerType.All(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get server types: %w", err)
}
serverNamesMap := make(map[int64]string)
for _, st := range serverTypes {
name := st.Name
if st.IsDeprecated() {
name = fmt.Sprintf("(%s)", name)
}
serverNamesMap[st.ID] = name
}
dsList, err := client.Datacenter.All(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get server types: %w", err)
}
serverTypesMap := make(map[string][]string)
for _, ds := range dsList {
for _, st := range ds.ServerTypes.Available {
serverTypesMap[ds.Name] = append(serverTypesMap[ds.Name], serverNamesMap[st.ID])
}
}
return serverTypesMap, nil
}Metadata
Metadata
Assignees
Labels
No labels