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: use --poll-interval flag #660

Merged
merged 1 commit into from
Jan 9, 2024
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
9 changes: 9 additions & 0 deletions internal/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/hetznercloud/cli/internal/cmd/version"
"github.com/hetznercloud/cli/internal/cmd/volume"
"github.com/hetznercloud/cli/internal/state"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)

func NewRootCommand(s state.State) *cobra.Command {
Expand Down Expand Up @@ -63,5 +64,13 @@ func NewRootCommand(s state.State) *cobra.Command {
)
cmd.PersistentFlags().Duration("poll-interval", 500*time.Millisecond, "Interval at which to poll information, for example action progress")
cmd.SetOut(os.Stdout)
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
pollInterval, err := cmd.Flags().GetDuration("poll-interval")
if err != nil {
return err
}
s.Client().WithOpts(hcloud.WithPollBackoffFunc(hcloud.ConstantBackoff(pollInterval)))
return nil
}
return cmd
}
20 changes: 20 additions & 0 deletions internal/hcapi2/action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package hcapi2

import (
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)

// ActionClient embeds the Hetzner Cloud Action client
type ActionClient interface {
hcloud.IActionClient
}

func NewActionClient(client hcloud.IActionClient) ActionClient {
return &actionClient{
IActionClient: client,
}
}

type actionClient struct {
hcloud.IActionClient
}
146 changes: 89 additions & 57 deletions internal/hcapi2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

// Client makes all API clients accessible via a single interface.
type Client interface {
Action() ActionClient
Datacenter() DatacenterClient
Firewall() FirewallClient
FloatingIP() FloatingIPClient
Expand All @@ -25,10 +26,11 @@ type Client interface {
PlacementGroup() PlacementGroupClient
RDNS() RDNSClient
PrimaryIP() PrimaryIPClient
WithOpts(...hcloud.ClientOption)
}

type client struct {
client *hcloud.Client
type clientCache struct {
actionClient ActionClient
certificateClient CertificateClient
datacenterClient DatacenterClient
serverClient ServerClient
Expand All @@ -46,162 +48,192 @@ type client struct {
placementGroupClient PlacementGroupClient
rdnsClient RDNSClient
primaryIPClient PrimaryIPClient
}

type client struct {
client *hcloud.Client
cache clientCache

mu sync.Mutex
mu sync.Mutex
opts []hcloud.ClientOption
}

// NewClient creates a new CLI API client extending hcloud.Client.
func NewClient(c *hcloud.Client) Client {
return &client{
client: c,
func NewClient(opts ...hcloud.ClientOption) Client {
c := &client{
opts: opts,
}
c.update()
return c
}

func (c *client) WithOpts(opts ...hcloud.ClientOption) {
c.mu.Lock()
defer c.mu.Unlock()
c.opts = append(c.opts, opts...)
c.update()
}

func (c *client) update() {
c.client = hcloud.NewClient(c.opts...)
c.cache = clientCache{}
}

func (c *client) Action() ActionClient {
c.mu.Lock()
if c.cache.actionClient == nil {
c.cache.actionClient = NewActionClient(&c.client.Action)
}
defer c.mu.Unlock()
return c.cache.actionClient
}

func (c *client) Certificate() CertificateClient {
c.mu.Lock()
if c.certificateClient == nil {
c.certificateClient = NewCertificateClient(&c.client.Certificate)
if c.cache.certificateClient == nil {
c.cache.certificateClient = NewCertificateClient(&c.client.Certificate)
}
defer c.mu.Unlock()
return c.certificateClient
return c.cache.certificateClient
}

func (c *client) Datacenter() DatacenterClient {
c.mu.Lock()
if c.datacenterClient == nil {
c.datacenterClient = NewDatacenterClient(&c.client.Datacenter)
if c.cache.datacenterClient == nil {
c.cache.datacenterClient = NewDatacenterClient(&c.client.Datacenter)
}
defer c.mu.Unlock()
return c.datacenterClient
return c.cache.datacenterClient
}

func (c *client) Firewall() FirewallClient {
c.mu.Lock()
if c.firewallClient == nil {
c.firewallClient = NewFirewallClient(&c.client.Firewall)
if c.cache.firewallClient == nil {
c.cache.firewallClient = NewFirewallClient(&c.client.Firewall)
}
defer c.mu.Unlock()
return c.firewallClient
return c.cache.firewallClient
}

func (c *client) FloatingIP() FloatingIPClient {
c.mu.Lock()
if c.floatingIPClient == nil {
c.floatingIPClient = NewFloatingIPClient(&c.client.FloatingIP)
if c.cache.floatingIPClient == nil {
c.cache.floatingIPClient = NewFloatingIPClient(&c.client.FloatingIP)
}
defer c.mu.Unlock()
return c.floatingIPClient
return c.cache.floatingIPClient
}

func (c *client) PrimaryIP() PrimaryIPClient {
c.mu.Lock()
if c.primaryIPClient == nil {
c.primaryIPClient = NewPrimaryIPClient(&c.client.PrimaryIP)
if c.cache.primaryIPClient == nil {
c.cache.primaryIPClient = NewPrimaryIPClient(&c.client.PrimaryIP)
}
defer c.mu.Unlock()
return c.primaryIPClient
return c.cache.primaryIPClient
}

func (c *client) Image() ImageClient {
c.mu.Lock()
if c.imageClient == nil {
c.imageClient = NewImageClient(&c.client.Image)
if c.cache.imageClient == nil {
c.cache.imageClient = NewImageClient(&c.client.Image)
}
defer c.mu.Unlock()
return c.imageClient
return c.cache.imageClient
}

func (c *client) ISO() ISOClient {
c.mu.Lock()
if c.isoClient == nil {
c.isoClient = NewISOClient(&c.client.ISO)
if c.cache.isoClient == nil {
c.cache.isoClient = NewISOClient(&c.client.ISO)
}
defer c.mu.Unlock()
return c.isoClient
return c.cache.isoClient
}

func (c *client) Location() LocationClient {
c.mu.Lock()
if c.locationClient == nil {
c.locationClient = NewLocationClient(&c.client.Location)
if c.cache.locationClient == nil {
c.cache.locationClient = NewLocationClient(&c.client.Location)
}
defer c.mu.Unlock()
return c.locationClient
return c.cache.locationClient
}

func (c *client) LoadBalancer() LoadBalancerClient {
c.mu.Lock()
if c.loadBalancerClient == nil {
c.loadBalancerClient = NewLoadBalancerClient(&c.client.LoadBalancer)
if c.cache.loadBalancerClient == nil {
c.cache.loadBalancerClient = NewLoadBalancerClient(&c.client.LoadBalancer)
}
defer c.mu.Unlock()
return c.loadBalancerClient
return c.cache.loadBalancerClient
}
func (c *client) LoadBalancerType() LoadBalancerTypeClient {
c.mu.Lock()
if c.loadBalancerTypeClient == nil {
c.loadBalancerTypeClient = NewLoadBalancerTypeClient(&c.client.LoadBalancerType)
if c.cache.loadBalancerTypeClient == nil {
c.cache.loadBalancerTypeClient = NewLoadBalancerTypeClient(&c.client.LoadBalancerType)
}
defer c.mu.Unlock()
return c.loadBalancerTypeClient
return c.cache.loadBalancerTypeClient
}
func (c *client) Network() NetworkClient {
c.mu.Lock()
if c.networkClient == nil {
c.networkClient = NewNetworkClient(&c.client.Network)
if c.cache.networkClient == nil {
c.cache.networkClient = NewNetworkClient(&c.client.Network)
}
defer c.mu.Unlock()
return c.networkClient
return c.cache.networkClient
}

func (c *client) Server() ServerClient {
c.mu.Lock()
if c.serverClient == nil {
c.serverClient = NewServerClient(&c.client.Server)
if c.cache.serverClient == nil {
c.cache.serverClient = NewServerClient(&c.client.Server)
}
defer c.mu.Unlock()
return c.serverClient
return c.cache.serverClient
}

func (c *client) ServerType() ServerTypeClient {
c.mu.Lock()
if c.serverTypeClient == nil {
c.serverTypeClient = NewServerTypeClient(&c.client.ServerType)
if c.cache.serverTypeClient == nil {
c.cache.serverTypeClient = NewServerTypeClient(&c.client.ServerType)
}
defer c.mu.Unlock()
return c.serverTypeClient
return c.cache.serverTypeClient
}

func (c *client) SSHKey() SSHKeyClient {
c.mu.Lock()
if c.sshKeyClient == nil {
c.sshKeyClient = NewSSHKeyClient(&c.client.SSHKey)
if c.cache.sshKeyClient == nil {
c.cache.sshKeyClient = NewSSHKeyClient(&c.client.SSHKey)
}
defer c.mu.Unlock()
return c.sshKeyClient
return c.cache.sshKeyClient
}
func (c *client) RDNS() RDNSClient {
c.mu.Lock()
if c.rdnsClient == nil {
c.rdnsClient = NewRDNSClient(&c.client.RDNS)
if c.cache.rdnsClient == nil {
c.cache.rdnsClient = NewRDNSClient(&c.client.RDNS)
}
defer c.mu.Unlock()
return c.rdnsClient
return c.cache.rdnsClient
}

func (c *client) Volume() VolumeClient {
c.mu.Lock()
if c.volumeClient == nil {
c.volumeClient = NewVolumeClient(&c.client.Volume)
if c.cache.volumeClient == nil {
c.cache.volumeClient = NewVolumeClient(&c.client.Volume)
}
defer c.mu.Unlock()
return c.volumeClient
return c.cache.volumeClient
}

func (c *client) PlacementGroup() PlacementGroupClient {
c.mu.Lock()
if c.placementGroupClient == nil {
c.placementGroupClient = NewPlacementGroupClient(&c.client.PlacementGroup)
if c.cache.placementGroupClient == nil {
c.cache.placementGroupClient = NewPlacementGroupClient(&c.client.PlacementGroup)
}
defer c.mu.Unlock()
return c.placementGroupClient
return c.cache.placementGroupClient
}
13 changes: 13 additions & 0 deletions internal/hcapi2/mock/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"github.com/golang/mock/gomock"

"github.com/hetznercloud/cli/internal/hcapi2"
"github.com/hetznercloud/hcloud-go/v2/hcloud"
)

type MockClient struct {
ActionClient *MockActionClient
CertificateClient *MockCertificateClient
DatacenterClient *MockDatacenterClient
FirewallClient *MockFirewallClient
Expand All @@ -28,6 +30,7 @@ type MockClient struct {

func NewMockClient(ctrl *gomock.Controller) *MockClient {
return &MockClient{
ActionClient: NewMockActionClient(ctrl),
CertificateClient: NewMockCertificateClient(ctrl),
DatacenterClient: NewMockDatacenterClient(ctrl),
FirewallClient: NewMockFirewallClient(ctrl),
Expand All @@ -47,9 +50,15 @@ func NewMockClient(ctrl *gomock.Controller) *MockClient {
RDNSClient: NewMockRDNSClient(ctrl),
}
}

func (c *MockClient) Action() hcapi2.ActionClient {
return c.ActionClient
}

func (c *MockClient) Certificate() hcapi2.CertificateClient {
return c.CertificateClient
}

func (c *MockClient) Datacenter() hcapi2.DatacenterClient {
return c.DatacenterClient
}
Expand Down Expand Up @@ -112,3 +121,7 @@ func (c *MockClient) RDNS() hcapi2.RDNSClient {
func (c *MockClient) PlacementGroup() hcapi2.PlacementGroupClient {
return c.PlacementGroupClient
}

func (*MockClient) WithOpts(...hcloud.ClientOption) {
// no-op
}
1 change: 1 addition & 0 deletions internal/hcapi2/mock/mock_gen.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hcapi2_mock

//go:generate mockgen -package hcapi2_mock -destination zz_action_client_mock.go github.com/hetznercloud/cli/internal/hcapi2 ActionClient
//go:generate mockgen -package hcapi2_mock -destination zz_certificate_client_mock.go github.com/hetznercloud/cli/internal/hcapi2 CertificateClient
//go:generate mockgen -package hcapi2_mock -destination zz_datacenter_client_mock.go github.com/hetznercloud/cli/internal/hcapi2 DatacenterClient
//go:generate mockgen -package hcapi2_mock -destination zz_image_client_mock.go github.com/hetznercloud/cli/internal/hcapi2 ImageClient
Expand Down
Loading
Loading