From 9b21c3f2490b6d2838ad644ba02269790735dc2e Mon Sep 17 00:00:00 2001 From: pauhull Date: Tue, 19 Dec 2023 12:39:03 +0100 Subject: [PATCH 1/5] fix create command YAML output --- internal/cmd/base/create.go | 24 +--- internal/cmd/certificate/create.go | 33 +++-- internal/cmd/certificate/create_test.go | 88 ++++-------- .../testdata/managed_create_response.json | 2 +- .../testdata/uploaded_create_response.json | 2 +- internal/cmd/firewall/create.go | 14 +- internal/cmd/firewall/create_test.go | 50 +++---- .../firewall/testdata/create_response.json | 2 +- internal/cmd/floatingip/create.go | 19 ++- internal/cmd/floatingip/create_test.go | 31 +--- .../floatingip/testdata/create_response.json | 6 +- internal/cmd/loadbalancer/create.go | 15 +- internal/cmd/loadbalancer/create_test.go | 51 +++---- internal/cmd/network/create.go | 18 ++- internal/cmd/network/create_test.go | 25 +--- .../cmd/network/testdata/create_response.json | 2 +- internal/cmd/placementgroup/create.go | 20 +-- internal/cmd/placementgroup/create_test.go | 42 ++---- .../testdata/create_response.json | 2 +- internal/cmd/primaryip/create.go | 19 ++- internal/cmd/primaryip/create_test.go | 44 ++---- .../primaryip/testdata/create_response.json | 2 +- internal/cmd/server/create.go | 13 +- internal/cmd/server/create_test.go | 133 ++++++++---------- .../cmd/server/testdata/create_response.json | 2 +- internal/cmd/sshkey/create.go | 14 +- internal/cmd/sshkey/create_test.go | 27 +--- .../cmd/sshkey/testdata/create_response.json | 2 +- internal/cmd/volume/create.go | 24 ++-- internal/cmd/volume/create_test.go | 34 ++--- .../cmd/volume/testdata/create_response.json | 2 +- internal/testutil/testing.go | 25 ---- 32 files changed, 313 insertions(+), 474 deletions(-) diff --git a/internal/cmd/base/create.go b/internal/cmd/base/create.go index b379c35e..cbd75019 100644 --- a/internal/cmd/base/create.go +++ b/internal/cmd/base/create.go @@ -2,8 +2,6 @@ package base import ( "context" - "encoding/json" - "io" "os" "github.com/spf13/cobra" @@ -12,14 +10,15 @@ 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" ) // CreateCmd allows defining commands for resource creation type CreateCmd struct { BaseCobraCommand func(hcapi2.Client) *cobra.Command - Run func(context.Context, hcapi2.Client, state.ActionWaiter, *cobra.Command, []string) (*hcloud.Response, any, error) - PrintResource func(context.Context, hcapi2.Client, *cobra.Command, any) + // Run is the function that will be called when the command is executed. + // It should return the created resource, the schema of the resource and an error. + Run func(context.Context, hcapi2.Client, state.ActionWaiter, *cobra.Command, []string) (any, any, error) + PrintResource func(context.Context, hcapi2.Client, *cobra.Command, any) } // CobraCommand creates a command that can be registered with cobra. @@ -53,29 +52,18 @@ func (cc *CreateCmd) CobraCommand( cmd.SetOut(os.Stdout) } - response, resource, err := cc.Run(ctx, client, actionWaiter, cmd, args) + resource, schema, err := cc.Run(ctx, client, actionWaiter, cmd, args) if err != nil { return err } if isSchema { - bytes, _ := io.ReadAll(response.Body) - - var schema map[string]any - if err := json.Unmarshal(bytes, &schema); err != nil { - return err - } - - delete(schema, "action") - delete(schema, "actions") - delete(schema, "next_actions") - if outputFlags.IsSet("json") { return util.DescribeJSON(schema) } else { return util.DescribeYAML(schema) } - } else if resource != nil { + } else if cc.PrintResource != nil && resource != nil { cc.PrintResource(ctx, client, cmd, resource) } return nil diff --git a/internal/cmd/certificate/create.go b/internal/cmd/certificate/create.go index dafd5fbd..0a63ac1e 100644 --- a/internal/cmd/certificate/create.go +++ b/internal/cmd/certificate/create.go @@ -13,6 +13,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -41,26 +42,30 @@ var CreateCmd = base.CreateCmd{ return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, strings []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, strings []string) (any, any, error) { certType, err := cmd.Flags().GetString("type") if err != nil { return nil, nil, err } + var cert *hcloud.Certificate switch hcloud.CertificateType(certType) { case hcloud.CertificateTypeManaged: - response, err := createManaged(ctx, client, waiter, cmd) - return response, nil, err + cert, err = createManaged(ctx, client, waiter, cmd) default: // Uploaded - response, err := createUploaded(ctx, client, cmd) - return response, nil, err + cert, err = createUploaded(ctx, client, cmd) } - }, - PrintResource: func(_ context.Context, _ hcapi2.Client, _ *cobra.Command, _ any) { - // no-op + if err != nil { + return nil, nil, err + } + return cert, struct { + Certificate schema.Certificate `json:"certificate"` + }{ + Certificate: hcloud.SchemaFromCertificate(cert), + }, nil }, } -func createUploaded(ctx context.Context, client hcapi2.Client, cmd *cobra.Command) (*hcloud.Response, error) { +func createUploaded(ctx context.Context, client hcapi2.Client, cmd *cobra.Command) (*hcloud.Certificate, error) { var ( name string certFile, keyFile string @@ -96,15 +101,15 @@ func createUploaded(ctx context.Context, client hcapi2.Client, cmd *cobra.Comman Certificate: string(certPEM), PrivateKey: string(keyPEM), } - cert, response, err := client.Certificate().Create(ctx, createOpts) + cert, _, err = client.Certificate().Create(ctx, createOpts) if err != nil { return nil, err } cmd.Printf("Certificate %d created\n", cert.ID) - return response, nil + return cert, nil } -func createManaged(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command) (*hcloud.Response, error) { +func createManaged(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command) (*hcloud.Certificate, error) { var ( name string domains []string @@ -127,7 +132,7 @@ func createManaged(ctx context.Context, client hcapi2.Client, waiter state.Actio Type: hcloud.CertificateTypeManaged, DomainNames: domains, } - res, response, err := client.Certificate().CreateCertificate(ctx, createOpts) + res, _, err = client.Certificate().CreateCertificate(ctx, createOpts) if err != nil { return nil, err } @@ -135,5 +140,5 @@ func createManaged(ctx context.Context, client hcapi2.Client, waiter state.Actio return nil, err } cmd.Printf("Certificate %d created\n", res.Certificate.ID) - return response, nil + return res.Certificate, nil } diff --git a/internal/cmd/certificate/create_test.go b/internal/cmd/certificate/create_test.go index 78befde7..d46435fe 100644 --- a/internal/cmd/certificate/create_test.go +++ b/internal/cmd/certificate/create_test.go @@ -11,7 +11,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/managed_create_response.json @@ -68,33 +67,6 @@ func TestCreateManagedJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.CertificateCreateResponse{ - Certificate: schema.Certificate{ - ID: 123, - Name: "test", - Type: string(hcloud.CertificateTypeManaged), - Created: time.Date(2020, 8, 24, 12, 0, 0, 0, time.UTC), - NotValidBefore: time.Date(2020, 8, 24, 12, 0, 0, 0, time.UTC), - NotValidAfter: time.Date(2036, 8, 12, 12, 0, 0, 0, time.UTC), - DomainNames: []string{"example.com"}, - Labels: map[string]string{"key": "value"}, - UsedBy: []schema.CertificateUsedByRef{{ - ID: 123, - Type: string(hcloud.CertificateUsedByRefTypeLoadBalancer), - }}, - Status: &schema.CertificateStatusRef{ - Error: &schema.Error{ - Code: "cert_error", - Message: "Certificate error", - }, - }, - }, - }) - - if err != nil { - t.Fatal(err) - } - fx.Client.CertificateClient.EXPECT(). CreateCertificate(gomock.Any(), hcloud.CertificateCreateOpts{ Name: "test", @@ -103,13 +75,27 @@ func TestCreateManagedJSON(t *testing.T) { }). Return(hcloud.CertificateCreateResult{ Certificate: &hcloud.Certificate{ - ID: 123, - Name: "test", - Type: hcloud.CertificateTypeManaged, - DomainNames: []string{"example.com"}, + ID: 123, + Name: "test", + Type: hcloud.CertificateTypeManaged, + Created: time.Date(2020, 8, 24, 12, 0, 0, 0, time.UTC), + NotValidBefore: time.Date(2020, 8, 24, 12, 0, 0, 0, time.UTC), + NotValidAfter: time.Date(2036, 8, 12, 12, 0, 0, 0, time.UTC), + DomainNames: []string{"example.com"}, + Labels: map[string]string{"key": "value"}, + UsedBy: []hcloud.CertificateUsedByRef{{ + ID: 123, + Type: hcloud.CertificateUsedByRefTypeLoadBalancer, + }}, + Status: &hcloud.CertificateStatus{ + Error: &hcloud.Error{ + Code: "cert_error", + Message: "Certificate error", + }, + }, }, Action: &hcloud.Action{ID: 321}, - }, response, nil) + }, nil, nil) fx.ActionWaiter.EXPECT(). ActionProgress(gomock.Any(), &hcloud.Action{ID: 321}) @@ -166,39 +152,27 @@ func TestCreateUploadedJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.CertificateCreateResponse{ - Certificate: schema.Certificate{ + fx.Client.CertificateClient.EXPECT(). + Create(gomock.Any(), hcloud.CertificateCreateOpts{ + Name: "test", + Type: hcloud.CertificateTypeUploaded, + Certificate: "certificate file content", + PrivateKey: "key file content", + }). + Return(&hcloud.Certificate{ ID: 123, Name: "test", - Type: string(hcloud.CertificateTypeUploaded), + Type: hcloud.CertificateTypeUploaded, Created: time.Date(2020, 8, 24, 12, 0, 0, 0, time.UTC), NotValidBefore: time.Date(2020, 8, 24, 12, 0, 0, 0, time.UTC), NotValidAfter: time.Date(2036, 8, 12, 12, 0, 0, 0, time.UTC), Labels: map[string]string{"key": "value"}, Fingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", - UsedBy: []schema.CertificateUsedByRef{{ + UsedBy: []hcloud.CertificateUsedByRef{{ ID: 123, - Type: string(hcloud.CertificateUsedByRefTypeLoadBalancer), + Type: hcloud.CertificateUsedByRefTypeLoadBalancer, }}, - }, - }) - - if err != nil { - t.Fatal(err) - } - - fx.Client.CertificateClient.EXPECT(). - Create(gomock.Any(), hcloud.CertificateCreateOpts{ - Name: "test", - Type: hcloud.CertificateTypeUploaded, - Certificate: "certificate file content", - PrivateKey: "key file content", - }). - Return(&hcloud.Certificate{ - ID: 123, - Name: "test", - Type: hcloud.CertificateTypeUploaded, - }, response, nil) + }, nil, nil) jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", "test", "--key-file", "testdata/key.pem", "--cert-file", "testdata/cert.pem"}) diff --git a/internal/cmd/certificate/testdata/managed_create_response.json b/internal/cmd/certificate/testdata/managed_create_response.json index c4aa326b..7573ec26 100644 --- a/internal/cmd/certificate/testdata/managed_create_response.json +++ b/internal/cmd/certificate/testdata/managed_create_response.json @@ -31,4 +31,4 @@ } ] } -} \ No newline at end of file +} diff --git a/internal/cmd/certificate/testdata/uploaded_create_response.json b/internal/cmd/certificate/testdata/uploaded_create_response.json index ca99508c..6d8a0e52 100644 --- a/internal/cmd/certificate/testdata/uploaded_create_response.json +++ b/internal/cmd/certificate/testdata/uploaded_create_response.json @@ -20,4 +20,4 @@ } ] } -} \ No newline at end of file +} diff --git a/internal/cmd/firewall/create.go b/internal/cmd/firewall/create.go index bacf839c..a18de870 100644 --- a/internal/cmd/firewall/create.go +++ b/internal/cmd/firewall/create.go @@ -32,7 +32,7 @@ var CreateCmd = base.CreateCmd{ cmd.Flags().String("rules-file", "", "JSON file containing your routes (use - to read from stdin). The structure of the file needs to be the same as within the API: https://docs.hetzner.cloud/#firewalls-get-a-firewall ") return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, strings []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, strings []string) (any, any, error) { name, _ := cmd.Flags().GetString("name") labels, _ := cmd.Flags().GetStringToString("label") @@ -78,17 +78,21 @@ var CreateCmd = base.CreateCmd{ } } - result, response, err := client.Firewall().Create(ctx, opts) + res, _, err := client.Firewall().Create(ctx, opts) if err != nil { return nil, nil, err } - if err := waiter.WaitForActions(ctx, result.Actions); err != nil { + if err := waiter.WaitForActions(ctx, res.Actions); err != nil { return nil, nil, err } - cmd.Printf("Firewall %d created\n", result.Firewall.ID) + cmd.Printf("Firewall %d created\n", res.Firewall.ID) - return response, nil, err + return res.Firewall, struct { + Firewall schema.Firewall `json:"firewall"` + }{ + Firewall: hcloud.SchemaFromFirewall(res.Firewall), + }, err }, } diff --git a/internal/cmd/firewall/create_test.go b/internal/cmd/firewall/create_test.go index e1ac5c63..1f4b847c 100644 --- a/internal/cmd/firewall/create_test.go +++ b/internal/cmd/firewall/create_test.go @@ -3,6 +3,7 @@ package firewall import ( "context" _ "embed" + "net" "testing" "time" @@ -11,7 +12,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -62,33 +62,6 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.FirewallCreateResponse{ - Firewall: schema.Firewall{ - ID: 123, - Name: "test", - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - AppliedTo: []schema.FirewallResource{ - {Type: "server", Server: &schema.FirewallResourceServer{ - ID: 1, - }}, - }, - Labels: make(map[string]string), - Rules: []schema.FirewallRule{ - { - Direction: "in", - SourceIPs: make([]string, 0), - Protocol: "tcp", - Port: hcloud.Ptr("22"), - }, - }, - }, - Actions: make([]schema.Action, 0), - }) - - if err != nil { - t.Fatal(err) - } - fx.Client.FirewallClient.EXPECT(). Create(gomock.Any(), hcloud.FirewallCreateOpts{ Name: "test", @@ -96,11 +69,26 @@ func TestCreateJSON(t *testing.T) { }). Return(hcloud.FirewallCreateResult{ Firewall: &hcloud.Firewall{ - ID: 123, - Name: "test", + ID: 123, + Name: "test", + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + AppliedTo: []hcloud.FirewallResource{ + {Type: "server", Server: &hcloud.FirewallResourceServer{ + ID: 1, + }}, + }, + Labels: make(map[string]string), + Rules: []hcloud.FirewallRule{ + { + Direction: "in", + SourceIPs: []net.IPNet{}, + Protocol: "tcp", + Port: hcloud.Ptr("22"), + }, + }, }, Actions: []*hcloud.Action{{ID: 321}}, - }, response, nil) + }, nil, nil) fx.ActionWaiter.EXPECT(). WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 321}}) diff --git a/internal/cmd/firewall/testdata/create_response.json b/internal/cmd/firewall/testdata/create_response.json index 74f49203..632a19f6 100644 --- a/internal/cmd/firewall/testdata/create_response.json +++ b/internal/cmd/firewall/testdata/create_response.json @@ -20,4 +20,4 @@ } ] } -} \ No newline at end of file +} diff --git a/internal/cmd/floatingip/create.go b/internal/cmd/floatingip/create.go index 3e2c2ca0..f1ed5c97 100644 --- a/internal/cmd/floatingip/create.go +++ b/internal/cmd/floatingip/create.go @@ -12,6 +12,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -44,7 +45,7 @@ var CreateCmd = base.CreateCmd{ return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { typ, _ := cmd.Flags().GetString("type") if typ == "" { return nil, nil, errors.New("type is required") @@ -89,24 +90,28 @@ var CreateCmd = base.CreateCmd{ createOpts.Server = server } - result, response, err := client.FloatingIP().Create(ctx, createOpts) + res, _, err := client.FloatingIP().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if result.Action != nil { - if err := waiter.ActionProgress(ctx, result.Action); err != nil { + if res.Action != nil { + if err := waiter.ActionProgress(ctx, res.Action); err != nil { return nil, nil, err } } - cmd.Printf("Floating IP %d created\n", result.FloatingIP.ID) + cmd.Printf("Floating IP %d created\n", res.FloatingIP.ID) - if err := changeProtection(ctx, client, waiter, cmd, result.FloatingIP, true, protectionOps); err != nil { + if err := changeProtection(ctx, client, waiter, cmd, res.FloatingIP, true, protectionOps); err != nil { return nil, nil, err } - return response, result.FloatingIP, nil + return res.FloatingIP, struct { + FloatingIP schema.FloatingIP `json:"floating_ip"` + }{ + FloatingIP: hcloud.SchemaFromFloatingIP(res.FloatingIP), + }, nil }, PrintResource: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource any) { diff --git a/internal/cmd/floatingip/create_test.go b/internal/cmd/floatingip/create_test.go index 291b3676..12670aa4 100644 --- a/internal/cmd/floatingip/create_test.go +++ b/internal/cmd/floatingip/create_test.go @@ -11,7 +11,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -67,24 +66,6 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.FloatingIPCreateResponse{ - FloatingIP: schema.FloatingIP{ - ID: 123, - Name: "myFloatingIP", - IP: "127.0.0.1", - Type: string(hcloud.FloatingIPTypeIPv4), - Labels: make(map[string]string), - Server: hcloud.Ptr(int64(1)), - }, - Action: &schema.Action{ - ID: 321, - }, - }) - - if err != nil { - t.Fatal(err) - } - fx.Client.FloatingIPClient.EXPECT(). Create(gomock.Any(), hcloud.FloatingIPCreateOpts{ Name: hcloud.Ptr("myFloatingIP"), @@ -95,13 +76,15 @@ func TestCreateJSON(t *testing.T) { }). Return(hcloud.FloatingIPCreateResult{ FloatingIP: &hcloud.FloatingIP{ - ID: 123, - Name: "myFloatingIP", - IP: net.ParseIP("192.168.2.1"), - Type: hcloud.FloatingIPTypeIPv4, + ID: 123, + Name: "myFloatingIP", + IP: net.ParseIP("127.0.0.1"), + Type: hcloud.FloatingIPTypeIPv4, + Labels: map[string]string{}, + Server: &hcloud.Server{ID: 1}, }, Action: nil, - }, response, nil) + }, nil, nil) jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", "myFloatingIP", "--type", "ipv4", "--home-location", "fsn1"}) diff --git a/internal/cmd/floatingip/testdata/create_response.json b/internal/cmd/floatingip/testdata/create_response.json index 3a8bd407..db8abcba 100644 --- a/internal/cmd/floatingip/testdata/create_response.json +++ b/internal/cmd/floatingip/testdata/create_response.json @@ -2,8 +2,8 @@ "floating_ip": { "blocked": false, "created": "0001-01-01T00:00:00Z", - "description": null, - "dns_ptr": null, + "description": "", + "dns_ptr": [], "home_location": { "city": "", "country": "", @@ -24,4 +24,4 @@ "server": 1, "type": "ipv4" } -} \ No newline at end of file +} diff --git a/internal/cmd/loadbalancer/create.go b/internal/cmd/loadbalancer/create.go index fb4785b8..d52275bc 100644 --- a/internal/cmd/loadbalancer/create.go +++ b/internal/cmd/loadbalancer/create.go @@ -10,6 +10,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -47,7 +48,7 @@ var CreateCmd = base.CreateCmd{ return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { name, _ := cmd.Flags().GetString("name") serverType, _ := cmd.Flags().GetString("type") algorithmType, _ := cmd.Flags().GetString("algorithm-type") @@ -77,15 +78,15 @@ var CreateCmd = base.CreateCmd{ if location != "" { createOpts.Location = &hcloud.Location{Name: location} } - result, response, err := client.LoadBalancer().Create(ctx, createOpts) + res, _, err := client.LoadBalancer().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if err := waiter.ActionProgress(ctx, result.Action); err != nil { + if err := waiter.ActionProgress(ctx, res.Action); err != nil { return nil, nil, err } - loadBalancer, _, err := client.LoadBalancer().GetByID(ctx, result.LoadBalancer.ID) + loadBalancer, _, err := client.LoadBalancer().GetByID(ctx, res.LoadBalancer.ID) if err != nil { return nil, nil, err } @@ -95,7 +96,11 @@ var CreateCmd = base.CreateCmd{ return nil, nil, err } - return response, loadBalancer, nil + return loadBalancer, struct { + LoadBalancer schema.LoadBalancer `json:"load_balancer"` + }{ + LoadBalancer: hcloud.SchemaFromLoadBalancer(loadBalancer), + }, nil }, PrintResource: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource any) { diff --git a/internal/cmd/loadbalancer/create_test.go b/internal/cmd/loadbalancer/create_test.go index 45b3cd6e..de7ec009 100644 --- a/internal/cmd/loadbalancer/create_test.go +++ b/internal/cmd/loadbalancer/create_test.go @@ -12,7 +12,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -77,28 +76,22 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.LoadBalancerCreateResponse{ - LoadBalancer: schema.LoadBalancer{ - ID: 123, - Name: "myLoadBalancer", - PublicNet: schema.LoadBalancerPublicNet{ - IPv4: schema.LoadBalancerPublicNetIPv4{ - IP: "192.168.2.1", - }, - IPv6: schema.LoadBalancerPublicNetIPv6{ - IP: "::", - }, + lb := &hcloud.LoadBalancer{ + ID: 123, + Name: "myLoadBalancer", + PublicNet: hcloud.LoadBalancerPublicNet{ + IPv4: hcloud.LoadBalancerPublicNetIPv4{ + IP: net.ParseIP("192.168.2.1"), + }, + IPv6: hcloud.LoadBalancerPublicNetIPv6{ + IP: net.IPv6zero, }, - Labels: make(map[string]string), - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - IncludedTraffic: 654321, - Services: make([]schema.LoadBalancerService, 0), - Targets: make([]schema.LoadBalancerTarget, 0), }, - }) - - if err != nil { - t.Fatal(err) + Labels: make(map[string]string), + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + IncludedTraffic: 654321, + Services: []hcloud.LoadBalancerService{}, + Targets: []hcloud.LoadBalancerTarget{}, } fx.Client.LoadBalancerClient.EXPECT(). @@ -109,23 +102,13 @@ func TestCreateJSON(t *testing.T) { Labels: make(map[string]string), }). Return(hcloud.LoadBalancerCreateResult{ - LoadBalancer: &hcloud.LoadBalancer{ID: 123}, + LoadBalancer: lb, Action: &hcloud.Action{ID: 321}, - }, response, nil) + }, nil, nil) fx.ActionWaiter.EXPECT().ActionProgress(gomock.Any(), &hcloud.Action{ID: 321}).Return(nil) fx.Client.LoadBalancerClient.EXPECT(). GetByID(gomock.Any(), int64(123)). - Return(&hcloud.LoadBalancer{ - ID: 123, - PublicNet: hcloud.LoadBalancerPublicNet{ - IPv4: hcloud.LoadBalancerPublicNetIPv4{ - IP: net.ParseIP("192.168.2.1"), - }, - IPv6: hcloud.LoadBalancerPublicNetIPv6{ - IP: net.IPv6zero, - }, - }, - }, nil, nil) + Return(lb, nil, nil) jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", "myLoadBalancer", "--type", "lb11", "--location", "fsn1"}) diff --git a/internal/cmd/network/create.go b/internal/cmd/network/create.go index 77e6decd..d91dcc6c 100644 --- a/internal/cmd/network/create.go +++ b/internal/cmd/network/create.go @@ -11,6 +11,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -35,7 +36,7 @@ var CreateCmd = base.CreateCmd{ cmd.RegisterFlagCompletionFunc("enable-protection", cmpl.SuggestCandidates("delete")) return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { name, _ := cmd.Flags().GetString("name") ipRange, _ := cmd.Flags().GetIPNet("ip-range") labels, _ := cmd.Flags().GetStringToString("label") @@ -54,16 +55,21 @@ var CreateCmd = base.CreateCmd{ ExposeRoutesToVSwitch: exposeRoutesToVSwitch, } - network, response, err := client.Network().Create(ctx, createOpts) + network, _, err := client.Network().Create(ctx, createOpts) if err != nil { return nil, nil, err } cmd.Printf("Network %d created\n", network.ID) - return response, nil, changeProtection(ctx, client, waiter, cmd, network, true, protectionOpts) - }, - PrintResource: func(_ context.Context, _ hcapi2.Client, _ *cobra.Command, _ any) { - // no-op + if err := changeProtection(ctx, client, waiter, cmd, network, true, protectionOpts); err != nil { + return nil, nil, err + } + + return network, struct { + Network schema.Network `json:"network"` + }{ + Network: hcloud.SchemaFromNetwork(network), + }, nil }, } diff --git a/internal/cmd/network/create_test.go b/internal/cmd/network/create_test.go index ab8d99a9..d3593ee0 100644 --- a/internal/cmd/network/create_test.go +++ b/internal/cmd/network/create_test.go @@ -12,7 +12,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -63,23 +62,6 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.NetworkCreateResponse{ - Network: schema.Network{ - ID: 123, - Name: "myNetwork", - IPRange: "10.0.0.0/24", - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - Labels: make(map[string]string), - Servers: []int64{1, 2, 3}, - Routes: make([]schema.NetworkRoute, 0), - Subnets: make([]schema.NetworkSubnet, 0), - }, - }) - - if err != nil { - t.Fatal(err) - } - _, ipRange, _ := net.ParseCIDR("10.0.0.0/24") fx.Client.NetworkClient.EXPECT(). Create(gomock.Any(), hcloud.NetworkCreateOpts{ @@ -91,7 +73,12 @@ func TestCreateJSON(t *testing.T) { ID: 123, Name: "myNetwork", IPRange: ipRange, - }, response, nil) + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + Labels: make(map[string]string), + Servers: []*hcloud.Server{{ID: 1}, {ID: 2}, {ID: 3}}, + Routes: []hcloud.NetworkRoute{}, + Subnets: []hcloud.NetworkSubnet{}, + }, nil, nil) jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", "myNetwork", "--ip-range", "10.0.0.0/24"}) diff --git a/internal/cmd/network/testdata/create_response.json b/internal/cmd/network/testdata/create_response.json index 11983669..55f124eb 100644 --- a/internal/cmd/network/testdata/create_response.json +++ b/internal/cmd/network/testdata/create_response.json @@ -17,4 +17,4 @@ ], "subnets": [] } -} \ No newline at end of file +} diff --git a/internal/cmd/placementgroup/create.go b/internal/cmd/placementgroup/create.go index 7a4443f8..4b9bcdfa 100644 --- a/internal/cmd/placementgroup/create.go +++ b/internal/cmd/placementgroup/create.go @@ -9,6 +9,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -26,7 +27,7 @@ var CreateCmd = base.CreateCmd{ cmd.MarkFlagRequired("type") return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { name, _ := cmd.Flags().GetString("name") labels, _ := cmd.Flags().GetStringToString("label") placementGroupType, _ := cmd.Flags().GetString("type") @@ -37,22 +38,23 @@ var CreateCmd = base.CreateCmd{ Type: hcloud.PlacementGroupType(placementGroupType), } - result, response, err := client.PlacementGroup().Create(ctx, opts) + res, _, err := client.PlacementGroup().Create(ctx, opts) if err != nil { return nil, nil, err } - if result.Action != nil { - if err := waiter.ActionProgress(ctx, result.Action); err != nil { + if res.Action != nil { + if err := waiter.ActionProgress(ctx, res.Action); err != nil { return nil, nil, err } } - cmd.Printf("Placement group %d created\n", result.PlacementGroup.ID) + cmd.Printf("Placement group %d created\n", res.PlacementGroup.ID) - return response, nil, nil - }, - PrintResource: func(_ context.Context, _ hcapi2.Client, _ *cobra.Command, _ any) { - // no-op + return res.PlacementGroup, struct { + PlacementGroup schema.PlacementGroup `json:"placement_group"` + }{ + PlacementGroup: hcloud.SchemaFromPlacementGroup(res.PlacementGroup), + }, nil }, } diff --git a/internal/cmd/placementgroup/create_test.go b/internal/cmd/placementgroup/create_test.go index 244a8f73..bad49154 100644 --- a/internal/cmd/placementgroup/create_test.go +++ b/internal/cmd/placementgroup/create_test.go @@ -12,7 +12,6 @@ import ( "github.com/hetznercloud/cli/internal/cmd/placementgroup" "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -72,47 +71,30 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.PlacementGroupCreateResponse{ - PlacementGroup: schema.PlacementGroup{ - ID: 897, - Name: "myPlacementGroup", - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - Servers: []int64{1, 2, 3}, - Labels: make(map[string]string), - Type: string(hcloud.PlacementGroupTypeSpread), - }, - Action: &schema.Action{ID: 321}, - }) - - if err != nil { - t.Fatal(err) - } - opts := hcloud.PlacementGroupCreateOpts{ - Name: "my Placement Group", + Name: "myPlacementGroup", Labels: map[string]string{}, Type: hcloud.PlacementGroupTypeSpread, } - placementGroup := hcloud.PlacementGroup{ - ID: 897, - Name: opts.Name, - Created: time.Now(), - Labels: opts.Labels, - Type: opts.Type, - } - fx.Client.PlacementGroupClient.EXPECT(). Create(gomock.Any(), opts). Return(hcloud.PlacementGroupCreateResult{ - PlacementGroup: &placementGroup, - Action: &hcloud.Action{ID: 321}, - }, response, nil) + PlacementGroup: &hcloud.PlacementGroup{ + ID: 897, + Name: "myPlacementGroup", + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + Servers: []int64{1, 2, 3}, + Labels: make(map[string]string), + Type: hcloud.PlacementGroupTypeSpread, + }, + Action: &hcloud.Action{ID: 321}, + }, nil, nil) fx.ActionWaiter.EXPECT(). ActionProgress(gomock.Any(), &hcloud.Action{ID: 321}) - jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", placementGroup.Name, "--type", string(placementGroup.Type)}) + jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", "myPlacementGroup", "--type", "spread"}) expOut := "Placement group 897 created\n" diff --git a/internal/cmd/placementgroup/testdata/create_response.json b/internal/cmd/placementgroup/testdata/create_response.json index 52770f5c..c918ea80 100644 --- a/internal/cmd/placementgroup/testdata/create_response.json +++ b/internal/cmd/placementgroup/testdata/create_response.json @@ -11,4 +11,4 @@ ], "type": "spread" } -} \ No newline at end of file +} diff --git a/internal/cmd/primaryip/create.go b/internal/cmd/primaryip/create.go index 25efa20e..f99259b9 100644 --- a/internal/cmd/primaryip/create.go +++ b/internal/cmd/primaryip/create.go @@ -10,6 +10,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -40,7 +41,7 @@ var CreateCmd = base.CreateCmd{ return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { typ, _ := cmd.Flags().GetString("type") name, _ := cmd.Flags().GetString("name") assigneeID, _ := cmd.Flags().GetInt64("assignee-id") @@ -62,26 +63,30 @@ var CreateCmd = base.CreateCmd{ createOpts.AssigneeID = &assigneeID } - result, response, err := client.PrimaryIP().Create(ctx, createOpts) + res, _, err := client.PrimaryIP().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if result.Action != nil { - if err := waiter.ActionProgress(ctx, result.Action); err != nil { + if res.Action != nil { + if err := waiter.ActionProgress(ctx, res.Action); err != nil { return nil, nil, err } } - cmd.Printf("Primary IP %d created\n", result.PrimaryIP.ID) + cmd.Printf("Primary IP %d created\n", res.PrimaryIP.ID) if len(protection) > 0 { - if err := changeProtection(ctx, client, waiter, cmd, result.PrimaryIP, true, protectionOpts); err != nil { + if err := changeProtection(ctx, client, waiter, cmd, res.PrimaryIP, true, protectionOpts); err != nil { return nil, nil, err } } - return response, result.PrimaryIP, nil + return res.PrimaryIP, struct { + PrimaryIP schema.PrimaryIP `json:"primary_ip"` + }{ + PrimaryIP: hcloud.SchemaFromPrimaryIP(res.PrimaryIP), + }, nil }, PrintResource: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource any) { primaryIP := resource.(*hcloud.PrimaryIP) diff --git a/internal/cmd/primaryip/create_test.go b/internal/cmd/primaryip/create_test.go index 8af91a8d..231adf4c 100644 --- a/internal/cmd/primaryip/create_test.go +++ b/internal/cmd/primaryip/create_test.go @@ -12,7 +12,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -73,33 +72,6 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.PrimaryIPCreateResponse{ - PrimaryIP: schema.PrimaryIP{ - ID: 1, - Name: "my-ip", - IP: "192.168.2.1", - Type: "ipv4", - Datacenter: schema.Datacenter{ - ID: 1, - Name: "fsn1-dc14", - Location: schema.Location{ID: 1, Name: "fsn1"}, - }, - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - Labels: make(map[string]string), - AutoDelete: true, - AssigneeID: 1, - AssigneeType: "server", - DNSPtr: make([]schema.PrimaryIPDNSPTR, 0), - }, - Action: &schema.Action{ - ID: 321, - }, - }) - - if err != nil { - t.Fatal(err) - } - fx.Client.PrimaryIPClient.EXPECT(). Create( gomock.Any(), @@ -114,11 +86,23 @@ func TestCreateJSON(t *testing.T) { &hcloud.PrimaryIPCreateResult{ PrimaryIP: &hcloud.PrimaryIP{ ID: 1, + Name: "my-ip", IP: net.ParseIP("192.168.2.1"), - Type: hcloud.PrimaryIPTypeIPv4, + Type: "ipv4", + Datacenter: &hcloud.Datacenter{ + ID: 1, + Name: "fsn1-dc14", + Location: &hcloud.Location{ID: 1, Name: "fsn1"}, + }, + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + Labels: make(map[string]string), + AutoDelete: true, + AssigneeID: 1, + AssigneeType: "server", + DNSPtr: map[string]string{}, }, Action: &hcloud.Action{ID: 321}, - }, response, nil) + }, nil, nil) fx.ActionWaiter.EXPECT(). ActionProgress(gomock.Any(), &hcloud.Action{ID: 321}) diff --git a/internal/cmd/primaryip/testdata/create_response.json b/internal/cmd/primaryip/testdata/create_response.json index dd17fa00..9ace047c 100644 --- a/internal/cmd/primaryip/testdata/create_response.json +++ b/internal/cmd/primaryip/testdata/create_response.json @@ -35,4 +35,4 @@ }, "type": "ipv4" } -} \ No newline at end of file +} diff --git a/internal/cmd/server/create.go b/internal/cmd/server/create.go index 92cd1957..bbb90937 100644 --- a/internal/cmd/server/create.go +++ b/internal/cmd/server/create.go @@ -20,6 +20,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) type createResult struct { @@ -27,6 +28,11 @@ type createResult struct { RootPassword string } +type createResultSchema struct { + Server schema.Server `json:"server"` + RootPassword string `json:"root_password,omitempty"` +} + // CreateCmd defines a command for creating a server. var CreateCmd = base.CreateCmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { @@ -91,13 +97,13 @@ var CreateCmd = base.CreateCmd{ return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, actionWaiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, actionWaiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { createOpts, protectionOpts, err := createOptsFromFlags(ctx, client, cmd) if err != nil { return nil, nil, err } - result, response, err := client.Server().Create(ctx, createOpts) + result, _, err := client.Server().Create(ctx, createOpts) if err != nil { return nil, nil, err } @@ -134,7 +140,8 @@ var CreateCmd = base.CreateCmd{ cmd.Printf("Backups enabled for server %d\n", server.ID) } - return response, createResult{Server: server, RootPassword: result.RootPassword}, nil + return createResult{Server: server, RootPassword: result.RootPassword}, + createResultSchema{Server: hcloud.SchemaFromServer(server), RootPassword: result.RootPassword}, nil }, PrintResource: func(_ context.Context, client hcapi2.Client, cmd *cobra.Command, resource any) { diff --git a/internal/cmd/server/create_test.go b/internal/cmd/server/create_test.go index 7bf8c68b..e9627d23 100644 --- a/internal/cmd/server/create_test.go +++ b/internal/cmd/server/create_test.go @@ -3,6 +3,7 @@ package server_test import ( "context" _ "embed" + "fmt" "net" "testing" "time" @@ -13,7 +14,6 @@ import ( "github.com/hetznercloud/cli/internal/cmd/server" "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -92,68 +92,57 @@ func TestCreateJSON(t *testing.T) { ) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.ServerCreateResponse{ - Server: schema.Server{ - ID: 1234, - Name: "cli-test", - PublicNet: schema.ServerPublicNet{ - IPv4: schema.ServerPublicNetIPv4{ - IP: "192.0.2.1", - }, + srv := &hcloud.Server{ + ID: 1234, + Name: "cli-test", + PublicNet: hcloud.ServerPublicNet{ + IPv4: hcloud.ServerPublicNetIPv4{ + IP: net.ParseIP("192.0.2.1"), }, - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - Labels: make(map[string]string), - Datacenter: schema.Datacenter{ + }, + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + Labels: make(map[string]string), + Datacenter: &hcloud.Datacenter{ + ID: 1, + Name: "fsn1-dc14", + Location: &hcloud.Location{ ID: 1, - Name: "fsn1-dc14", - Location: schema.Location{ - ID: 1, - Name: "fsn1", - }, - }, - ServerType: schema.ServerType{ - ID: 1, - Name: "cx11", - Cores: 1, - CPUType: "shared", - Memory: 2, - Disk: 20, - StorageType: "local", - Architecture: string(hcloud.ArchitectureX86), - }, - Image: &schema.Image{ - ID: 1, - Type: "system", - Status: "available", - Name: hcloud.Ptr("ubuntu-20.04"), - Description: "Ubuntu 20.04", - Deprecated: nil, - Labels: make(map[string]string), - OSFlavor: "ubuntu", - OSVersion: hcloud.Ptr("20.04"), - RapidDeploy: true, - Protection: schema.ImageProtection{ - Delete: true, - }, + Name: "fsn1", }, - ISO: &schema.ISO{ - ID: 1, - Name: "FreeBSD-11.0-RELEASE-amd64-dvd1", - Description: "FreeBSD 11.0 x64", - Type: "public", - Deprecated: nil, + }, + ServerType: &hcloud.ServerType{ + ID: 1, + Name: "cx11", + Cores: 1, + CPUType: "shared", + Memory: 2, + Disk: 20, + StorageType: "local", + Architecture: hcloud.ArchitectureX86, + }, + Image: &hcloud.Image{ + ID: 1, + Type: "system", + Status: "available", + Name: "ubuntu-20.04", + Description: "Ubuntu 20.04", + Labels: make(map[string]string), + OSFlavor: "ubuntu", + OSVersion: "20.04", + RapidDeploy: true, + Protection: hcloud.ImageProtection{ + Delete: true, }, - RescueEnabled: true, - Locked: true, - Status: string(hcloud.ServerStatusRunning), }, - NextActions: make([]schema.Action, 0), - RootPassword: hcloud.Ptr("secret"), - Action: schema.Action{ID: 123}, - }) - - if err != nil { - t.Fatal(err) + ISO: &hcloud.ISO{ + ID: 1, + Name: "FreeBSD-11.0-RELEASE-amd64-dvd1", + Description: "FreeBSD 11.0 x64", + Type: "public", + }, + RescueEnabled: true, + Locked: true, + Status: hcloud.ServerStatusRunning, } fx.Client.ServerTypeClient.EXPECT(). @@ -168,27 +157,14 @@ func TestCreateJSON(t *testing.T) { assert.Equal(t, "cli-test", opts.Name) }). Return(hcloud.ServerCreateResult{ - Server: &hcloud.Server{ - ID: 1234, - PublicNet: hcloud.ServerPublicNet{ - IPv4: hcloud.ServerPublicNetIPv4{ - IP: net.ParseIP("192.0.2.1"), - }, - }, - }, - Action: &hcloud.Action{ID: 123}, - NextActions: []*hcloud.Action{{ID: 234}}, - }, response, nil) + Server: srv, + RootPassword: "secret", + Action: &hcloud.Action{ID: 123}, + NextActions: []*hcloud.Action{{ID: 234}}, + }, nil, nil) fx.Client.ServerClient.EXPECT(). GetByID(gomock.Any(), int64(1234)). - Return(&hcloud.Server{ - ID: 1234, - PublicNet: hcloud.ServerPublicNet{ - IPv4: hcloud.ServerPublicNetIPv4{ - IP: net.ParseIP("192.0.2.1"), - }, - }, - }, nil, nil) + Return(srv, nil, nil) fx.ActionWaiter.EXPECT().ActionProgress(gomock.Any(), &hcloud.Action{ID: 123}).Return(nil) fx.ActionWaiter.EXPECT().WaitForActions(gomock.Any(), []*hcloud.Action{{ID: 234}}).Return(nil) @@ -199,6 +175,9 @@ func TestCreateJSON(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expOut, out) + + fmt.Println(jsonOut) + assert.JSONEq(t, createResponseJson, jsonOut) } diff --git a/internal/cmd/server/testdata/create_response.json b/internal/cmd/server/testdata/create_response.json index c051a64f..5d56c63d 100644 --- a/internal/cmd/server/testdata/create_response.json +++ b/internal/cmd/server/testdata/create_response.json @@ -80,7 +80,7 @@ }, "ipv6": { "blocked": false, - "dns_ptr": null, + "dns_ptr": [], "id": 0, "ip": "" } diff --git a/internal/cmd/sshkey/create.go b/internal/cmd/sshkey/create.go index df1b8644..fec2fb03 100644 --- a/internal/cmd/sshkey/create.go +++ b/internal/cmd/sshkey/create.go @@ -11,6 +11,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -30,7 +31,7 @@ var CreateCmd = base.CreateCmd{ cmd.Flags().StringToString("label", nil, "User-defined labels ('key=value') (can be specified multiple times)") return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { name, _ := cmd.Flags().GetString("name") publicKey, _ := cmd.Flags().GetString("public-key") publicKeyFile, _ := cmd.Flags().GetString("public-key-from-file") @@ -57,16 +58,17 @@ var CreateCmd = base.CreateCmd{ PublicKey: publicKey, Labels: labels, } - sshKey, response, err := client.SSHKey().Create(ctx, opts) + sshKey, _, err := client.SSHKey().Create(ctx, opts) if err != nil { return nil, nil, err } cmd.Printf("SSH key %d created\n", sshKey.ID) - return response, nil, nil - }, - PrintResource: func(_ context.Context, _ hcapi2.Client, _ *cobra.Command, _ any) { - // no-op + return sshKey, struct { + SSHKey schema.SSHKey `json:"ssh_key"` + }{ + SSHKey: hcloud.SchemaFromSSHKey(sshKey), + }, nil }, } diff --git a/internal/cmd/sshkey/create_test.go b/internal/cmd/sshkey/create_test.go index 6c21a5a2..78a98c3d 100644 --- a/internal/cmd/sshkey/create_test.go +++ b/internal/cmd/sshkey/create_test.go @@ -11,7 +11,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -61,21 +60,6 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.SSHKeyCreateResponse{ - SSHKey: schema.SSHKey{ - ID: 123, - Name: "test", - PublicKey: "test", - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - Labels: make(map[string]string), - Fingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", - }, - }) - - if err != nil { - t.Fatal(err) - } - fx.Client.SSHKeyClient.EXPECT(). Create(gomock.Any(), hcloud.SSHKeyCreateOpts{ Name: "test", @@ -83,10 +67,13 @@ func TestCreateJSON(t *testing.T) { Labels: make(map[string]string), }). Return(&hcloud.SSHKey{ - ID: 123, - Name: "test", - PublicKey: "test", - }, response, nil) + ID: 123, + Name: "test", + PublicKey: "test", + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + Labels: make(map[string]string), + Fingerprint: "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", + }, nil, nil) jsonOut, out, err := fx.Run(cmd, []string{"-o=json", "--name", "test", "--public-key", "test"}) diff --git a/internal/cmd/sshkey/testdata/create_response.json b/internal/cmd/sshkey/testdata/create_response.json index 334c32ff..91c244ad 100644 --- a/internal/cmd/sshkey/testdata/create_response.json +++ b/internal/cmd/sshkey/testdata/create_response.json @@ -7,4 +7,4 @@ "name": "test", "public_key": "test" } -} \ No newline at end of file +} diff --git a/internal/cmd/volume/create.go b/internal/cmd/volume/create.go index 473a03f5..7508e1de 100644 --- a/internal/cmd/volume/create.go +++ b/internal/cmd/volume/create.go @@ -12,6 +12,7 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -47,7 +48,7 @@ var CreateCmd = base.CreateCmd{ return cmd }, - Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (*hcloud.Response, any, error) { + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) (any, any, error) { name, _ := cmd.Flags().GetString("name") serverIDOrName, _ := cmd.Flags().GetString("server") size, _ := cmd.Flags().GetInt("size") @@ -93,22 +94,27 @@ var CreateCmd = base.CreateCmd{ createOpts.Format = &format } - result, response, err := client.Volume().Create(ctx, createOpts) + res, _, err := client.Volume().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if err := waiter.ActionProgress(ctx, result.Action); err != nil { + if err := waiter.ActionProgress(ctx, res.Action); err != nil { return nil, nil, err } - if err := waiter.WaitForActions(ctx, result.NextActions); err != nil { + if err := waiter.WaitForActions(ctx, res.NextActions); err != nil { return nil, nil, err } - cmd.Printf("Volume %d created\n", result.Volume.ID) + cmd.Printf("Volume %d created\n", res.Volume.ID) - return response, nil, changeProtection(ctx, client, waiter, cmd, result.Volume, true, protectionOpts) - }, - PrintResource: func(_ context.Context, _ hcapi2.Client, _ *cobra.Command, _ any) { - // no-op + if err := changeProtection(ctx, client, waiter, cmd, res.Volume, true, protectionOpts); err != nil { + return nil, nil, err + } + + return res.Volume, struct { + Volume schema.Volume `json:"volume"` + }{ + Volume: hcloud.SchemaFromVolume(res.Volume), + }, nil }, } diff --git a/internal/cmd/volume/create_test.go b/internal/cmd/volume/create_test.go index 49d8cc57..dad6368e 100644 --- a/internal/cmd/volume/create_test.go +++ b/internal/cmd/volume/create_test.go @@ -11,7 +11,6 @@ import ( "github.com/hetznercloud/cli/internal/testutil" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) //go:embed testdata/create_response.json @@ -71,30 +70,6 @@ func TestCreateJSON(t *testing.T) { fx.ActionWaiter) fx.ExpectEnsureToken() - response, err := testutil.MockResponse(&schema.VolumeCreateResponse{ - Volume: schema.Volume{ - ID: 123, - Name: "test", - Size: 20, - Location: schema.Location{Name: "fsn1"}, - Labels: make(map[string]string), - Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), - Status: string(hcloud.VolumeStatusAvailable), - Protection: schema.VolumeProtection{ - Delete: true, - }, - Server: hcloud.Ptr(int64(123)), - }, - Action: &schema.Action{ - ID: 321, - }, - NextActions: make([]schema.Action, 0), - }) - - if err != nil { - t.Fatal(err) - } - fx.Client.VolumeClient.EXPECT(). Create(gomock.Any(), hcloud.VolumeCreateOpts{ Name: "test", @@ -108,10 +83,17 @@ func TestCreateJSON(t *testing.T) { Name: "test", Size: 20, Location: &hcloud.Location{Name: "fsn1"}, + Labels: make(map[string]string), + Created: time.Date(2016, 1, 30, 23, 50, 0, 0, time.UTC), + Status: hcloud.VolumeStatusAvailable, + Protection: hcloud.VolumeProtection{ + Delete: true, + }, + Server: &hcloud.Server{ID: 123}, }, Action: &hcloud.Action{ID: 321}, NextActions: []*hcloud.Action{{ID: 1}, {ID: 2}, {ID: 3}}, - }, response, nil) + }, nil, nil) fx.ActionWaiter.EXPECT(). ActionProgress(gomock.Any(), &hcloud.Action{ID: 321}) fx.ActionWaiter.EXPECT(). diff --git a/internal/cmd/volume/testdata/create_response.json b/internal/cmd/volume/testdata/create_response.json index d8b11854..6620a107 100644 --- a/internal/cmd/volume/testdata/create_response.json +++ b/internal/cmd/volume/testdata/create_response.json @@ -22,4 +22,4 @@ "size": 20, "status": "available" } -} \ No newline at end of file +} diff --git a/internal/testutil/testing.go b/internal/testutil/testing.go index 1d7d4ffd..5caa143f 100644 --- a/internal/testutil/testing.go +++ b/internal/testutil/testing.go @@ -2,13 +2,9 @@ package testutil import ( "bytes" - "encoding/json" "fmt" "io" - "net/http/httptest" "os" - - "github.com/hetznercloud/hcloud-go/v2/hcloud" ) // CaptureOutStreams redirects stdout & stderr while running fn and returns the outputs as a string. @@ -66,24 +62,3 @@ func CaptureOutStreams(fn func() error) (string, string, error) { return outBuf.String(), errBuf.String(), err } - -// MockResponse returns a *hcloud.Response with the given value as JSON body. -func MockResponse[V any](v V) (*hcloud.Response, error) { - - responseBytes, err := json.MarshalIndent(v, "", " ") - if err != nil { - return nil, err - } - - responseRecorder := httptest.NewRecorder() - responseRecorder.WriteHeader(200) - - _, err = responseRecorder.Write(responseBytes) - if err != nil { - return nil, err - } - - return &hcloud.Response{ - Response: responseRecorder.Result(), - }, nil -} From df7e863463a7bbcea6d83cecd766e7144e53f20d Mon Sep 17 00:00:00 2001 From: jo Date: Wed, 20 Dec 2023 12:21:54 +0100 Subject: [PATCH 2/5] chore: remove debug prints --- internal/cmd/server/create_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/cmd/server/create_test.go b/internal/cmd/server/create_test.go index e9627d23..cc350104 100644 --- a/internal/cmd/server/create_test.go +++ b/internal/cmd/server/create_test.go @@ -3,7 +3,6 @@ package server_test import ( "context" _ "embed" - "fmt" "net" "testing" "time" @@ -176,8 +175,6 @@ func TestCreateJSON(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expOut, out) - fmt.Println(jsonOut) - assert.JSONEq(t, createResponseJson, jsonOut) } From 724090275b779a976cf692a6b6a83eba2738ece1 Mon Sep 17 00:00:00 2001 From: jo Date: Wed, 20 Dec 2023 12:28:48 +0100 Subject: [PATCH 3/5] suggestion: use map[string]any and a small util function --- internal/cmd/certificate/create.go | 7 +------ internal/cmd/util/util.go | 7 +++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/cmd/certificate/create.go b/internal/cmd/certificate/create.go index 0a63ac1e..10da3cee 100644 --- a/internal/cmd/certificate/create.go +++ b/internal/cmd/certificate/create.go @@ -13,7 +13,6 @@ import ( "github.com/hetznercloud/cli/internal/hcapi2" "github.com/hetznercloud/cli/internal/state" "github.com/hetznercloud/hcloud-go/v2/hcloud" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -57,11 +56,7 @@ var CreateCmd = base.CreateCmd{ if err != nil { return nil, nil, err } - return cert, struct { - Certificate schema.Certificate `json:"certificate"` - }{ - Certificate: hcloud.SchemaFromCertificate(cert), - }, nil + return cert, util.WrapSchema("certificate", hcloud.SchemaFromCertificate(cert)), nil }, } diff --git a/internal/cmd/util/util.go b/internal/cmd/util/util.go index 8662b5dd..1407feb2 100644 --- a/internal/cmd/util/util.go +++ b/internal/cmd/util/util.go @@ -165,6 +165,13 @@ func DescribeYAML(object interface{}) error { return enc.Encode(object) } +// WrapSchema return a map wrapping the schema (value) in a dict (`{ key: value }`). +// +// Used to reduce boilerplate. +func WrapSchema(key string, value any) map[string]any { + return map[string]any{key: value} +} + // ValidateRequiredFlags ensures that flags has values for all flags with // the passed names. // From 52a9b0895a5b6b65eeb0a972f40f33b804a37869 Mon Sep 17 00:00:00 2001 From: pauhull Date: Wed, 20 Dec 2023 13:42:51 +0100 Subject: [PATCH 4/5] refactor: use util.Wrap to wrap JSON --- internal/cmd/certificate/create.go | 2 +- internal/cmd/firewall/create.go | 7 ++----- internal/cmd/floatingip/create.go | 8 ++------ internal/cmd/loadbalancer/create.go | 8 ++------ internal/cmd/network/create.go | 8 ++------ internal/cmd/placementgroup/create.go | 8 ++------ internal/cmd/primaryip/create.go | 8 ++------ internal/cmd/sshkey/create.go | 8 ++------ internal/cmd/util/util.go | 6 +++--- internal/cmd/volume/create.go | 8 ++------ 10 files changed, 20 insertions(+), 51 deletions(-) diff --git a/internal/cmd/certificate/create.go b/internal/cmd/certificate/create.go index 10da3cee..d2531f39 100644 --- a/internal/cmd/certificate/create.go +++ b/internal/cmd/certificate/create.go @@ -56,7 +56,7 @@ var CreateCmd = base.CreateCmd{ if err != nil { return nil, nil, err } - return cert, util.WrapSchema("certificate", hcloud.SchemaFromCertificate(cert)), nil + return cert, util.Wrap("certificate", hcloud.SchemaFromCertificate(cert)), nil }, } diff --git a/internal/cmd/firewall/create.go b/internal/cmd/firewall/create.go index a18de870..0eac98b4 100644 --- a/internal/cmd/firewall/create.go +++ b/internal/cmd/firewall/create.go @@ -11,6 +11,7 @@ import ( "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" @@ -89,10 +90,6 @@ var CreateCmd = base.CreateCmd{ cmd.Printf("Firewall %d created\n", res.Firewall.ID) - return res.Firewall, struct { - Firewall schema.Firewall `json:"firewall"` - }{ - Firewall: hcloud.SchemaFromFirewall(res.Firewall), - }, err + return res.Firewall, util.Wrap("firewall", hcloud.SchemaFromFirewall(res.Firewall)), err }, } diff --git a/internal/cmd/floatingip/create.go b/internal/cmd/floatingip/create.go index f1ed5c97..d33802d3 100644 --- a/internal/cmd/floatingip/create.go +++ b/internal/cmd/floatingip/create.go @@ -9,10 +9,10 @@ import ( "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/cmd/cmpl" + "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -107,11 +107,7 @@ var CreateCmd = base.CreateCmd{ return nil, nil, err } - return res.FloatingIP, struct { - FloatingIP schema.FloatingIP `json:"floating_ip"` - }{ - FloatingIP: hcloud.SchemaFromFloatingIP(res.FloatingIP), - }, nil + return res.FloatingIP, util.Wrap("floating_ip", hcloud.SchemaFromFloatingIP(res.FloatingIP)), nil }, PrintResource: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource any) { diff --git a/internal/cmd/loadbalancer/create.go b/internal/cmd/loadbalancer/create.go index d52275bc..c7364695 100644 --- a/internal/cmd/loadbalancer/create.go +++ b/internal/cmd/loadbalancer/create.go @@ -7,10 +7,10 @@ import ( "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/cmd/cmpl" + "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -96,11 +96,7 @@ var CreateCmd = base.CreateCmd{ return nil, nil, err } - return loadBalancer, struct { - LoadBalancer schema.LoadBalancer `json:"load_balancer"` - }{ - LoadBalancer: hcloud.SchemaFromLoadBalancer(loadBalancer), - }, nil + return loadBalancer, util.Wrap("load_balancer", hcloud.SchemaFromLoadBalancer(loadBalancer)), nil }, PrintResource: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource any) { diff --git a/internal/cmd/network/create.go b/internal/cmd/network/create.go index d91dcc6c..c22346f5 100644 --- a/internal/cmd/network/create.go +++ b/internal/cmd/network/create.go @@ -8,10 +8,10 @@ import ( "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/cmd/cmpl" + "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -66,10 +66,6 @@ var CreateCmd = base.CreateCmd{ return nil, nil, err } - return network, struct { - Network schema.Network `json:"network"` - }{ - Network: hcloud.SchemaFromNetwork(network), - }, nil + return network, util.Wrap("network", hcloud.SchemaFromNetwork(network)), nil }, } diff --git a/internal/cmd/placementgroup/create.go b/internal/cmd/placementgroup/create.go index 4b9bcdfa..707a47bf 100644 --- a/internal/cmd/placementgroup/create.go +++ b/internal/cmd/placementgroup/create.go @@ -6,10 +6,10 @@ import ( "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -51,10 +51,6 @@ var CreateCmd = base.CreateCmd{ cmd.Printf("Placement group %d created\n", res.PlacementGroup.ID) - return res.PlacementGroup, struct { - PlacementGroup schema.PlacementGroup `json:"placement_group"` - }{ - PlacementGroup: hcloud.SchemaFromPlacementGroup(res.PlacementGroup), - }, nil + return res.PlacementGroup, util.Wrap("placement_group", hcloud.SchemaFromPlacementGroup(res.PlacementGroup)), nil }, } diff --git a/internal/cmd/primaryip/create.go b/internal/cmd/primaryip/create.go index f99259b9..1599796c 100644 --- a/internal/cmd/primaryip/create.go +++ b/internal/cmd/primaryip/create.go @@ -7,10 +7,10 @@ import ( "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/cmd/cmpl" + "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -82,11 +82,7 @@ var CreateCmd = base.CreateCmd{ } } - return res.PrimaryIP, struct { - PrimaryIP schema.PrimaryIP `json:"primary_ip"` - }{ - PrimaryIP: hcloud.SchemaFromPrimaryIP(res.PrimaryIP), - }, nil + return res.PrimaryIP, util.Wrap("primary_ip", hcloud.SchemaFromPrimaryIP(res.PrimaryIP)), nil }, PrintResource: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource any) { primaryIP := resource.(*hcloud.PrimaryIP) diff --git a/internal/cmd/sshkey/create.go b/internal/cmd/sshkey/create.go index fec2fb03..def45d30 100644 --- a/internal/cmd/sshkey/create.go +++ b/internal/cmd/sshkey/create.go @@ -8,10 +8,10 @@ import ( "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -65,10 +65,6 @@ var CreateCmd = base.CreateCmd{ cmd.Printf("SSH key %d created\n", sshKey.ID) - return sshKey, struct { - SSHKey schema.SSHKey `json:"ssh_key"` - }{ - SSHKey: hcloud.SchemaFromSSHKey(sshKey), - }, nil + return sshKey, util.Wrap("ssh_key", hcloud.SchemaFromSSHKey(sshKey)), nil }, } diff --git a/internal/cmd/util/util.go b/internal/cmd/util/util.go index 1407feb2..08af39a4 100644 --- a/internal/cmd/util/util.go +++ b/internal/cmd/util/util.go @@ -165,10 +165,10 @@ func DescribeYAML(object interface{}) error { return enc.Encode(object) } -// WrapSchema return a map wrapping the schema (value) in a dict (`{ key: value }`). +// Wrap wraps the passed value in a map with the passed key. // -// Used to reduce boilerplate. -func WrapSchema(key string, value any) map[string]any { +// This is useful when working with JSON objects. +func Wrap(key string, value any) map[string]any { return map[string]any{key: value} } diff --git a/internal/cmd/volume/create.go b/internal/cmd/volume/create.go index 7508e1de..b65bff26 100644 --- a/internal/cmd/volume/create.go +++ b/internal/cmd/volume/create.go @@ -9,10 +9,10 @@ import ( "github.com/hetznercloud/cli/internal/cmd/base" "github.com/hetznercloud/cli/internal/cmd/cmpl" + "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" - "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) var CreateCmd = base.CreateCmd{ @@ -111,10 +111,6 @@ var CreateCmd = base.CreateCmd{ return nil, nil, err } - return res.Volume, struct { - Volume schema.Volume `json:"volume"` - }{ - Volume: hcloud.SchemaFromVolume(res.Volume), - }, nil + return res.Volume, util.Wrap("volume", hcloud.SchemaFromVolume(res.Volume)), nil }, } From 178c671ceb52ce989342c1c2b95f7ec62bc3d28a Mon Sep 17 00:00:00 2001 From: pauhull Date: Wed, 20 Dec 2023 14:14:54 +0100 Subject: [PATCH 5/5] undo refactor --- internal/cmd/firewall/create.go | 8 ++++---- internal/cmd/floatingip/create.go | 12 ++++++------ internal/cmd/loadbalancer/create.go | 6 +++--- internal/cmd/placementgroup/create.go | 10 +++++----- internal/cmd/primaryip/create.go | 12 ++++++------ internal/cmd/volume/create.go | 12 ++++++------ 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/internal/cmd/firewall/create.go b/internal/cmd/firewall/create.go index 0eac98b4..d2a688ca 100644 --- a/internal/cmd/firewall/create.go +++ b/internal/cmd/firewall/create.go @@ -79,17 +79,17 @@ var CreateCmd = base.CreateCmd{ } } - res, _, err := client.Firewall().Create(ctx, opts) + result, _, err := client.Firewall().Create(ctx, opts) if err != nil { return nil, nil, err } - if err := waiter.WaitForActions(ctx, res.Actions); err != nil { + if err := waiter.WaitForActions(ctx, result.Actions); err != nil { return nil, nil, err } - cmd.Printf("Firewall %d created\n", res.Firewall.ID) + cmd.Printf("Firewall %d created\n", result.Firewall.ID) - return res.Firewall, util.Wrap("firewall", hcloud.SchemaFromFirewall(res.Firewall)), err + return result.Firewall, util.Wrap("firewall", hcloud.SchemaFromFirewall(result.Firewall)), err }, } diff --git a/internal/cmd/floatingip/create.go b/internal/cmd/floatingip/create.go index d33802d3..11da8302 100644 --- a/internal/cmd/floatingip/create.go +++ b/internal/cmd/floatingip/create.go @@ -90,24 +90,24 @@ var CreateCmd = base.CreateCmd{ createOpts.Server = server } - res, _, err := client.FloatingIP().Create(ctx, createOpts) + result, _, err := client.FloatingIP().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if res.Action != nil { - if err := waiter.ActionProgress(ctx, res.Action); err != nil { + if result.Action != nil { + if err := waiter.ActionProgress(ctx, result.Action); err != nil { return nil, nil, err } } - cmd.Printf("Floating IP %d created\n", res.FloatingIP.ID) + cmd.Printf("Floating IP %d created\n", result.FloatingIP.ID) - if err := changeProtection(ctx, client, waiter, cmd, res.FloatingIP, true, protectionOps); err != nil { + if err := changeProtection(ctx, client, waiter, cmd, result.FloatingIP, true, protectionOps); err != nil { return nil, nil, err } - return res.FloatingIP, util.Wrap("floating_ip", hcloud.SchemaFromFloatingIP(res.FloatingIP)), nil + return result.FloatingIP, util.Wrap("floating_ip", hcloud.SchemaFromFloatingIP(result.FloatingIP)), nil }, PrintResource: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, resource any) { diff --git a/internal/cmd/loadbalancer/create.go b/internal/cmd/loadbalancer/create.go index c7364695..7088fe69 100644 --- a/internal/cmd/loadbalancer/create.go +++ b/internal/cmd/loadbalancer/create.go @@ -78,15 +78,15 @@ var CreateCmd = base.CreateCmd{ if location != "" { createOpts.Location = &hcloud.Location{Name: location} } - res, _, err := client.LoadBalancer().Create(ctx, createOpts) + result, _, err := client.LoadBalancer().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if err := waiter.ActionProgress(ctx, res.Action); err != nil { + if err := waiter.ActionProgress(ctx, result.Action); err != nil { return nil, nil, err } - loadBalancer, _, err := client.LoadBalancer().GetByID(ctx, res.LoadBalancer.ID) + loadBalancer, _, err := client.LoadBalancer().GetByID(ctx, result.LoadBalancer.ID) if err != nil { return nil, nil, err } diff --git a/internal/cmd/placementgroup/create.go b/internal/cmd/placementgroup/create.go index 707a47bf..1561613a 100644 --- a/internal/cmd/placementgroup/create.go +++ b/internal/cmd/placementgroup/create.go @@ -38,19 +38,19 @@ var CreateCmd = base.CreateCmd{ Type: hcloud.PlacementGroupType(placementGroupType), } - res, _, err := client.PlacementGroup().Create(ctx, opts) + result, _, err := client.PlacementGroup().Create(ctx, opts) if err != nil { return nil, nil, err } - if res.Action != nil { - if err := waiter.ActionProgress(ctx, res.Action); err != nil { + if result.Action != nil { + if err := waiter.ActionProgress(ctx, result.Action); err != nil { return nil, nil, err } } - cmd.Printf("Placement group %d created\n", res.PlacementGroup.ID) + cmd.Printf("Placement group %d created\n", result.PlacementGroup.ID) - return res.PlacementGroup, util.Wrap("placement_group", hcloud.SchemaFromPlacementGroup(res.PlacementGroup)), nil + return result.PlacementGroup, util.Wrap("placement_group", hcloud.SchemaFromPlacementGroup(result.PlacementGroup)), nil }, } diff --git a/internal/cmd/primaryip/create.go b/internal/cmd/primaryip/create.go index 1599796c..a482c663 100644 --- a/internal/cmd/primaryip/create.go +++ b/internal/cmd/primaryip/create.go @@ -63,26 +63,26 @@ var CreateCmd = base.CreateCmd{ createOpts.AssigneeID = &assigneeID } - res, _, err := client.PrimaryIP().Create(ctx, createOpts) + result, _, err := client.PrimaryIP().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if res.Action != nil { - if err := waiter.ActionProgress(ctx, res.Action); err != nil { + if result.Action != nil { + if err := waiter.ActionProgress(ctx, result.Action); err != nil { return nil, nil, err } } - cmd.Printf("Primary IP %d created\n", res.PrimaryIP.ID) + cmd.Printf("Primary IP %d created\n", result.PrimaryIP.ID) if len(protection) > 0 { - if err := changeProtection(ctx, client, waiter, cmd, res.PrimaryIP, true, protectionOpts); err != nil { + if err := changeProtection(ctx, client, waiter, cmd, result.PrimaryIP, true, protectionOpts); err != nil { return nil, nil, err } } - return res.PrimaryIP, util.Wrap("primary_ip", hcloud.SchemaFromPrimaryIP(res.PrimaryIP)), nil + return result.PrimaryIP, util.Wrap("primary_ip", hcloud.SchemaFromPrimaryIP(result.PrimaryIP)), nil }, PrintResource: func(_ context.Context, _ hcapi2.Client, cmd *cobra.Command, resource any) { primaryIP := resource.(*hcloud.PrimaryIP) diff --git a/internal/cmd/volume/create.go b/internal/cmd/volume/create.go index b65bff26..e81d75ba 100644 --- a/internal/cmd/volume/create.go +++ b/internal/cmd/volume/create.go @@ -94,23 +94,23 @@ var CreateCmd = base.CreateCmd{ createOpts.Format = &format } - res, _, err := client.Volume().Create(ctx, createOpts) + result, _, err := client.Volume().Create(ctx, createOpts) if err != nil { return nil, nil, err } - if err := waiter.ActionProgress(ctx, res.Action); err != nil { + if err := waiter.ActionProgress(ctx, result.Action); err != nil { return nil, nil, err } - if err := waiter.WaitForActions(ctx, res.NextActions); err != nil { + if err := waiter.WaitForActions(ctx, result.NextActions); err != nil { return nil, nil, err } - cmd.Printf("Volume %d created\n", res.Volume.ID) + cmd.Printf("Volume %d created\n", result.Volume.ID) - if err := changeProtection(ctx, client, waiter, cmd, res.Volume, true, protectionOpts); err != nil { + if err := changeProtection(ctx, client, waiter, cmd, result.Volume, true, protectionOpts); err != nil { return nil, nil, err } - return res.Volume, util.Wrap("volume", hcloud.SchemaFromVolume(res.Volume)), nil + return result.Volume, util.Wrap("volume", hcloud.SchemaFromVolume(result.Volume)), nil }, }