Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: integer fields are displayed as floats when using describe with -o=yaml #650

Merged
merged 2 commits into from
Dec 19, 2023
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
31 changes: 7 additions & 24 deletions internal/cmd/base/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package base

import (
"context"
"encoding/json"
"fmt"
"io"
"reflect"
"strings"

Expand All @@ -15,7 +13,6 @@ import (
"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"
)

// DescribeCmd allows defining commands for describing a resource.
Expand All @@ -27,8 +24,10 @@ type DescribeCmd struct {
JSONKeyGetByName string // e.g. "servers"
NameSuggestions func(client hcapi2.Client) func() []string
AdditionalFlags func(*cobra.Command)
Fetch func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error)
PrintText func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error
// Fetch is called to fetch the resource to describe.
// The first returned interface is the resource itself as a hcloud struct, the second is the schema for the resource.
Fetch func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error)
PrintText func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error
}

// CobraCommand creates a command that can be registered with cobra.
Expand Down Expand Up @@ -59,7 +58,7 @@ func (dc *DescribeCmd) Run(ctx context.Context, client hcapi2.Client, cmd *cobra
outputFlags := output.FlagsForCommand(cmd)

idOrName := args[0]
resource, resp, err := dc.Fetch(ctx, client, cmd, idOrName)
resource, schema, err := dc.Fetch(ctx, client, cmd, idOrName)
if err != nil {
return err
}
Expand All @@ -72,28 +71,12 @@ func (dc *DescribeCmd) Run(ctx context.Context, client hcapi2.Client, cmd *cobra

switch {
case outputFlags.IsSet("json"):
return dc.describe(resp.Body, util.DescribeJSON)
return util.DescribeJSON(schema)
case outputFlags.IsSet("yaml"):
return dc.describe(resp.Body, util.DescribeYAML)
return util.DescribeYAML(schema)
case outputFlags.IsSet("format"):
return util.DescribeFormat(resource, outputFlags["format"][0])
default:
return dc.PrintText(ctx, client, cmd, resource)
}
}

func (dc *DescribeCmd) describe(body io.ReadCloser, describeFunc func(interface{}) error) error {
var schema map[string]interface{}
if err := json.NewDecoder(body).Decode(&schema); err != nil {
return err
}
if resource, ok := schema[dc.JSONKeyGetByID]; ok {
return describeFunc(resource)
}
if resources, ok := schema[dc.JSONKeyGetByName].([]interface{}); ok {
// We check whether we got a resource at all above (see reflect-based nil check), so it's
// ok to assume there's an element in resources.
return describeFunc(resources[0])
}
return fmt.Errorf("got invalid JSON response")
}
8 changes: 6 additions & 2 deletions internal/cmd/certificate/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "certificate",
JSONKeyGetByName: "certificates",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Certificate().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Certificate().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
cert, _, err := client.Certificate().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return cert, hcloud.SchemaFromCertificate(cert), nil
},
PrintText: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
cert := resource.(*hcloud.Certificate)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/datacenter/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "datacenter",
JSONKeyGetByName: "datacenters",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Datacenter().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Datacenter().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
dc, _, err := client.Datacenter().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return dc, hcloud.SchemaFromDatacenter(dc), nil
},
PrintText: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
datacenter := resource.(*hcloud.Datacenter)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/firewall/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "firewall",
JSONKeyGetByName: "firewalls",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Firewall().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Firewall().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
fw, _, err := client.Firewall().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return fw, hcloud.SchemaFromFirewall(fw), nil
},
PrintText: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
firewall := resource.(*hcloud.Firewall)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/floatingip/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "floating_ip",
JSONKeyGetByName: "floating_ips",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.FloatingIP().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.FloatingIP().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
ip, _, err := client.FloatingIP().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return ip, hcloud.SchemaFromFloatingIP(ip), nil
},
PrintText: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
floatingIP := resource.(*hcloud.FloatingIP)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/image/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,19 @@ var DescribeCmd = base.DescribeCmd{

},
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Image().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
arch, err := cmd.Flags().GetString("architecture")
if err != nil {
return nil, nil, err
}
if !cmd.Flags().Changed("architecture") {
_, _ = fmt.Fprintln(os.Stderr, "INFO: This command only returns x86 images by default. Explicitly set the --architecture=x86|arm flag to hide this message.")
}
return client.Image().GetForArchitecture(ctx, idOrName, hcloud.Architecture(arch))
img, _, err := client.Image().GetForArchitecture(ctx, idOrName, hcloud.Architecture(arch))
if err != nil {
return nil, nil, err
}
return img, hcloud.SchemaFromImage(img), nil
},
PrintText: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
image := resource.(*hcloud.Image)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/iso/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "iso",
JSONKeyGetByName: "isos",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Location().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.ISO().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
iso, _, err := client.ISO().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return iso, hcloud.SchemaFromISO(iso), nil
},
PrintText: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
iso := resource.(*hcloud.ISO)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/loadbalancer/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "load_balancer",
JSONKeyGetByName: "load_balancers",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.LoadBalancer().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.LoadBalancer().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
lb, _, err := client.LoadBalancer().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return lb, hcloud.SchemaFromLoadBalancer(lb), nil
},
AdditionalFlags: func(cmd *cobra.Command) {
cmd.Flags().Bool("expand-targets", false, "Expand all label_selector targets")
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/loadbalancertype/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "load_balancer_type",
JSONKeyGetByName: "load_balancer_types",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.LoadBalancerType().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.LoadBalancerType().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
lbt, _, err := client.LoadBalancerType().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return lbt, hcloud.SchemaFromLoadBalancerType(lbt), nil
},
PrintText: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
loadBalancerType := resource.(*hcloud.LoadBalancerType)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/location/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "location",
JSONKeyGetByName: "locations",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Location().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Location().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
l, _, err := client.Location().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return l, hcloud.SchemaFromLocation(l), nil
},
PrintText: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
location := resource.(*hcloud.Location)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/network/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "network",
JSONKeyGetByName: "networks",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Network().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Network().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
n, _, err := client.Network().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return n, hcloud.SchemaFromNetwork(n), nil
},
PrintText: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
network := resource.(*hcloud.Network)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/placementgroup/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "placement_group",
JSONKeyGetByName: "placement_groups",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.PlacementGroup().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.PlacementGroup().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
pg, _, err := client.PlacementGroup().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return pg, hcloud.SchemaFromPlacementGroup(pg), nil
},
PrintText: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
placementGroup := resource.(*hcloud.PlacementGroup)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/primaryip/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "primary_ip",
JSONKeyGetByName: "primary_ips",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.PrimaryIP().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.PrimaryIP().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
ip, _, err := client.PrimaryIP().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return ip, hcloud.SchemaFromPrimaryIP(ip), nil
},
PrintText: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
primaryIP := resource.(*hcloud.PrimaryIP)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/server/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "server",
JSONKeyGetByName: "servers",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Server().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
srv, _, err := client.Server().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return srv, hcloud.SchemaFromServer(srv), nil
},
PrintText: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
server := resource.(*hcloud.Server)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/servertype/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "server_type",
JSONKeyGetByName: "server_types",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.ServerType().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.ServerType().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
st, _, err := client.ServerType().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return st, hcloud.SchemaFromServerType(st), nil
},
PrintText: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
serverType := resource.(*hcloud.ServerType)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/sshkey/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "ssh_key",
JSONKeyGetByName: "ssh_keys",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.SSHKey().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.SSHKey().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
key, _, err := client.SSHKey().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return key, hcloud.SchemaFromSSHKey(key), nil
},
PrintText: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
sshKey := resource.(*hcloud.SSHKey)
Expand Down
8 changes: 6 additions & 2 deletions internal/cmd/volume/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ var DescribeCmd = base.DescribeCmd{
JSONKeyGetByID: "volume",
JSONKeyGetByName: "volumes",
NameSuggestions: func(c hcapi2.Client) func() []string { return c.Volume().Names },
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
return client.Volume().Get(ctx, idOrName)
Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, interface{}, error) {
v, _, err := client.Volume().Get(ctx, idOrName)
if err != nil {
return nil, nil, err
}
return v, hcloud.SchemaFromVolume(v), nil
},
PrintText: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource interface{}) error {
volume := resource.(*hcloud.Volume)
Expand Down
Loading