diff --git a/go.mod b/go.mod index 2a580c26f01ab..5bb332422165c 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/google/go-tpm-tools v0.4.5 github.com/google/uuid v1.6.0 github.com/gophercloud/gophercloud/v2 v2.7.0 - github.com/hetznercloud/hcloud-go v1.59.2 + github.com/hetznercloud/hcloud-go/v2 v2.21.1 github.com/jacksontj/memberlistmesh v0.0.0-20190905163944-93462b9d2bb7 github.com/pelletier/go-toml v1.9.5 github.com/pkg/sftp v1.13.9 diff --git a/go.sum b/go.sum index fd93fd24675ad..e137991889453 100644 --- a/go.sum +++ b/go.sum @@ -375,8 +375,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hetznercloud/hcloud-go v1.59.2 h1:NkCPwYiPv85FnOV3IW9/gxfW61TPIUSwyPHRSLwCkHA= -github.com/hetznercloud/hcloud-go v1.59.2/go.mod h1:oTebZCjd+osj75jlI76Z+zjN1sTxmMiQ1MWoO8aRl1c= +github.com/hetznercloud/hcloud-go/v2 v2.21.1 h1:IH3liW8/cCRjfJ4cyqYvw3s1ek+KWP8dl1roa0lD8JM= +github.com/hetznercloud/hcloud-go/v2 v2.21.1/go.mod h1:XOaYycZJ3XKMVWzmqQ24/+1V7ormJHmPdck/kxrNnQA= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= diff --git a/nodeup/pkg/model/context.go b/nodeup/pkg/model/context.go index d19aea96c8eea..13af91e525554 100644 --- a/nodeup/pkg/model/context.go +++ b/nodeup/pkg/model/context.go @@ -27,7 +27,7 @@ import ( awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - hcloudmetadata "github.com/hetznercloud/hcloud-go/hcloud/metadata" + hcloudmetadata "github.com/hetznercloud/hcloud-go/v2/hcloud/metadata" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" kopsmodel "k8s.io/kops/pkg/apis/kops/model" diff --git a/pkg/model/hetznermodel/firewall.go b/pkg/model/hetznermodel/firewall.go index 0293675be71f4..d55dd7fd52a03 100644 --- a/pkg/model/hetznermodel/firewall.go +++ b/pkg/model/hetznermodel/firewall.go @@ -21,7 +21,7 @@ import ( "net" "strings" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" diff --git a/pkg/model/hetznermodel/loadbalancer.go b/pkg/model/hetznermodel/loadbalancer.go index 8e82a7107be59..46796db5b8f08 100644 --- a/pkg/model/hetznermodel/loadbalancer.go +++ b/pkg/model/hetznermodel/loadbalancer.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/wellknownports" "k8s.io/kops/pkg/wellknownservices" diff --git a/pkg/nodeidentity/hetzner/identify.go b/pkg/nodeidentity/hetzner/identify.go index 70e53cb7cd860..dfd8789de7329 100644 --- a/pkg/nodeidentity/hetzner/identify.go +++ b/pkg/nodeidentity/hetzner/identify.go @@ -24,7 +24,7 @@ import ( "strings" "time" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" corev1 "k8s.io/api/core/v1" expirationcache "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" @@ -138,7 +138,7 @@ func stringKeyFunc(obj interface{}) (string, error) { // getServer queries Hetzner Cloud for the server with the specified ID, returning an error if not found func (i *nodeIdentifier) getServer(id string) (*hcloud.Server, error) { - serverID, err := strconv.Atoi(id) + serverID, err := strconv.ParseInt(id, 10, 64) if err != nil { return nil, fmt.Errorf("failed to convert server ID %q to int: %w", id, err) } diff --git a/pkg/resources/hetzner/resources.go b/pkg/resources/hetzner/resources.go index 3109f8371029f..ed60da254f27d 100644 --- a/pkg/resources/hetzner/resources.go +++ b/pkg/resources/hetzner/resources.go @@ -21,7 +21,7 @@ import ( "fmt" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/resources" @@ -79,7 +79,7 @@ func listSSHKeys(cloud fi.Cloud, clusterName string) ([]*resources.Resource, err for _, sshKey := range sshKeys { resourceTracker := &resources.Resource{ Name: sshKey.Name, - ID: strconv.Itoa(sshKey.ID), + ID: strconv.FormatInt(sshKey.ID, 10), Type: resourceTypeSSHKey, Deleter: deleteSSHKey, Obj: sshKey, @@ -103,7 +103,7 @@ func listNetworks(cloud fi.Cloud, clusterName string) ([]*resources.Resource, er for _, network := range networks { resourceTracker := &resources.Resource{ Name: network.Name, - ID: strconv.Itoa(network.ID), + ID: strconv.FormatInt(network.ID, 10), Type: resourceTypeNetwork, Deleter: deleteNetwork, Obj: network, @@ -127,7 +127,7 @@ func listFirewalls(cloud fi.Cloud, clusterName string) ([]*resources.Resource, e for _, firewall := range firewalls { resourceTracker := &resources.Resource{ Name: firewall.Name, - ID: strconv.Itoa(firewall.ID), + ID: strconv.FormatInt(firewall.ID, 10), Type: resourceTypeFirewall, Deleter: deleteFirewall, Obj: firewall, @@ -151,7 +151,7 @@ func listLoadBalancers(cloud fi.Cloud, clusterName string) ([]*resources.Resourc for _, loadBalancer := range loadBalancers { resourceTracker := &resources.Resource{ Name: loadBalancer.Name, - ID: strconv.Itoa(loadBalancer.ID), + ID: strconv.FormatInt(loadBalancer.ID, 10), Type: resourceTypeLoadBalancer, Deleter: deleteLoadBalancer, Obj: loadBalancer, @@ -175,7 +175,7 @@ func listServers(cloud fi.Cloud, clusterName string) ([]*resources.Resource, err for _, server := range servers { resourceTracker := &resources.Resource{ Name: server.Name, - ID: strconv.Itoa(server.ID), + ID: strconv.FormatInt(server.ID, 10), Type: resourceTypeServer, Deleter: deleteServer, Dumper: dumpServer, @@ -204,7 +204,7 @@ func listVolumes(cloud fi.Cloud, clusterName string) ([]*resources.Resource, err for _, volume := range volumes { resourceTracker := &resources.Resource{ Name: volume.Name, - ID: strconv.Itoa(volume.ID), + ID: strconv.FormatInt(volume.ID, 10), Type: resourceTypeVolume, Deleter: deleteVolume, Obj: volume, diff --git a/protokube/pkg/gossip/hetzner/seeds.go b/protokube/pkg/gossip/hetzner/seeds.go index 466e6ea8e2def..75b1f89e70dc9 100644 --- a/protokube/pkg/gossip/hetzner/seeds.go +++ b/protokube/pkg/gossip/hetzner/seeds.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/klog/v2" "k8s.io/kops/protokube/pkg/gossip" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" diff --git a/protokube/pkg/protokube/hetzner_volume.go b/protokube/pkg/protokube/hetzner_volume.go index ae560e39fc093..abd6bf6d78156 100644 --- a/protokube/pkg/protokube/hetzner_volume.go +++ b/protokube/pkg/protokube/hetzner_volume.go @@ -21,8 +21,8 @@ import ( "fmt" "os" - "github.com/hetznercloud/hcloud-go/hcloud" - "github.com/hetznercloud/hcloud-go/hcloud/metadata" + "github.com/hetznercloud/hcloud-go/v2/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud/metadata" "k8s.io/klog/v2" "k8s.io/kops/protokube/pkg/gossip" gossiphetzner "k8s.io/kops/protokube/pkg/gossip/hetzner" diff --git a/upup/pkg/fi/cloudup/hetzner/authenticator.go b/upup/pkg/fi/cloudup/hetzner/authenticator.go index c39509ed1e715..45729bb8fd33b 100644 --- a/upup/pkg/fi/cloudup/hetzner/authenticator.go +++ b/upup/pkg/fi/cloudup/hetzner/authenticator.go @@ -20,7 +20,7 @@ import ( "fmt" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud/metadata" + "github.com/hetznercloud/hcloud-go/v2/hcloud/metadata" "k8s.io/kops/pkg/bootstrap" ) @@ -40,5 +40,5 @@ func (h *hetznerAuthenticator) CreateToken(body []byte) (string, error) { if err != nil { return "", fmt.Errorf("failed to retrieve server ID: %w", err) } - return HetznerAuthenticationTokenPrefix + strconv.Itoa(serverID), nil + return HetznerAuthenticationTokenPrefix + strconv.FormatInt(serverID, 10), nil } diff --git a/upup/pkg/fi/cloudup/hetzner/cloud.go b/upup/pkg/fi/cloudup/hetzner/cloud.go index e23701376b760..e3d3e9f0d3cdc 100644 --- a/upup/pkg/fi/cloudup/hetzner/cloud.go +++ b/upup/pkg/fi/cloudup/hetzner/cloud.go @@ -24,7 +24,7 @@ import ( "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" "k8s.io/kops/dnsprovider/pkg/dnsprovider" @@ -245,7 +245,7 @@ func (c *hetznerCloudImplementation) DNS() (dnsprovider.Interface, error) { } func (c *hetznerCloudImplementation) DeleteInstance(instance *cloudinstances.CloudInstance) error { - serverID, err := strconv.Atoi(instance.ID) + serverID, err := strconv.ParseInt(instance.ID, 10, 64) if err != nil { return fmt.Errorf("failed to convert server ID %q to int: %w", instance.ID, err) } @@ -256,20 +256,20 @@ func (c *hetznerCloudImplementation) DeleteInstance(instance *cloudinstances.Clo } // deleteServer shuts down and deletes the given server -func deleteServer(c *hetznerCloudImplementation, id int) error { +func deleteServer(c *hetznerCloudImplementation, id int64) error { client := c.ServerClient() ctx := context.TODO() server := &hcloud.Server{ID: id} _, _, err := client.Shutdown(ctx, server) if err != nil { - return fmt.Errorf("failed to stop server %q: %w", strconv.Itoa(id), err) + return fmt.Errorf("failed to stop server %q: %w", strconv.FormatInt(id, 10), err) } for i := 1; i <= 30; i++ { server, _, err := client.GetByID(ctx, id) if err != nil || server == nil { - return fmt.Errorf("failed to get info for server %q: %w", strconv.Itoa(id), err) + return fmt.Errorf("failed to get info for server %q: %w", strconv.FormatInt(id, 10), err) } if server.Status == hcloud.ServerStatusOff { @@ -281,7 +281,7 @@ func deleteServer(c *hetznerCloudImplementation, id int) error { _, err = client.Delete(ctx, server) if err != nil { - return fmt.Errorf("failed to delete server %q: %w", strconv.Itoa(id), err) + return fmt.Errorf("failed to delete server %q: %w", strconv.FormatInt(id, 10), err) } return nil @@ -374,7 +374,7 @@ func buildCloudInstanceGroup(ig *kops.InstanceGroup, sg []*hcloud.Server, nodeMa status = cloudinstances.CloudInstanceStatusNeedsUpdate } - id := strconv.Itoa(server.ID) + id := strconv.FormatInt(server.ID, 10) cloudInstance, err := cloudInstanceGroup.NewCloudInstance(id, status, nodeMap[id]) if err != nil { return nil, fmt.Errorf("failed to create cloud group instance for server %s(%d): %w", server.Name, server.ID, err) @@ -398,7 +398,7 @@ func buildCloudInstanceGroup(ig *kops.InstanceGroup, sg []*hcloud.Server, nodeMa func (c *hetznerCloudImplementation) DeleteGroup(g *cloudinstances.CloudInstanceGroup) error { for _, cloudInstance := range append(g.NeedUpdate, g.Ready...) { - serverID, err := strconv.Atoi(cloudInstance.ID) + serverID, err := strconv.ParseInt(cloudInstance.ID, 10, 64) if err != nil { return fmt.Errorf("failed to convert server ID %q to int: %w", cloudInstance.ID, err) } diff --git a/upup/pkg/fi/cloudup/hetzner/verifier.go b/upup/pkg/fi/cloudup/hetzner/verifier.go index e939f7ad3b2c6..ebe77373e1e12 100644 --- a/upup/pkg/fi/cloudup/hetzner/verifier.go +++ b/upup/pkg/fi/cloudup/hetzner/verifier.go @@ -25,7 +25,7 @@ import ( "strconv" "strings" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/pkg/bootstrap" "k8s.io/kops/pkg/wellknownports" ) @@ -63,7 +63,7 @@ func (h hetznerVerifier) VerifyToken(ctx context.Context, rawRequest *http.Reque } token = strings.TrimPrefix(token, HetznerAuthenticationTokenPrefix) - serverID, err := strconv.Atoi(token) + serverID, err := strconv.ParseInt(token, 10, 64) if err != nil { return nil, fmt.Errorf("failed to convert server ID %q to int: %w", token, err) } diff --git a/upup/pkg/fi/cloudup/hetznertasks/firewall.go b/upup/pkg/fi/cloudup/hetznertasks/firewall.go index 9ffb17d38180d..c1aa27d7f141a 100644 --- a/upup/pkg/fi/cloudup/hetznertasks/firewall.go +++ b/upup/pkg/fi/cloudup/hetznertasks/firewall.go @@ -21,7 +21,7 @@ import ( "net" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" "k8s.io/kops/upup/pkg/fi/cloudup/terraform" @@ -32,7 +32,7 @@ type Firewall struct { Name *string Lifecycle fi.Lifecycle - ID *int + ID *int64 Selector string Rules []*FirewallRule @@ -42,7 +42,7 @@ type Firewall struct { var _ fi.CompareWithID = &Firewall{} func (v *Firewall) CompareWithID() *string { - return fi.PtrTo(strconv.Itoa(fi.ValueOf(v.ID))) + return fi.PtrTo(strconv.FormatInt(fi.ValueOf(v.ID), 10)) } func (v *Firewall) Find(c *fi.CloudupContext) (*Firewall, error) { diff --git a/upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go b/upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go index fddae6eaf0f19..f2a0764c110d6 100644 --- a/upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go +++ b/upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go @@ -25,7 +25,7 @@ import ( "strconv" "strings" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/klog/v2" "k8s.io/kops/pkg/wellknownservices" "k8s.io/kops/upup/pkg/fi" @@ -40,7 +40,7 @@ type LoadBalancer struct { Lifecycle fi.Lifecycle Network *Network - ID *int + ID *int64 Location string Type string Services []*LoadBalancerService @@ -56,7 +56,7 @@ type LoadBalancer struct { var _ fi.CompareWithID = &LoadBalancer{} func (v *LoadBalancer) CompareWithID() *string { - return fi.PtrTo(strconv.Itoa(fi.ValueOf(v.ID))) + return fi.PtrTo(strconv.FormatInt(fi.ValueOf(v.ID), 10)) } var _ fi.HasAddress = &LoadBalancer{} @@ -234,7 +234,7 @@ func (_ *LoadBalancer) RenderHetzner(t *hetzner.HetznerAPITarget, a, e, changes return fmt.Errorf("failed to find network for loadbalancer %q", fi.ValueOf(e.Name)) } - networkID, err := strconv.Atoi(fi.ValueOf(e.Network.ID)) + networkID, err := strconv.ParseInt(fi.ValueOf(e.Network.ID), 10, 64) if err != nil { return fmt.Errorf("failed to convert network ID %q to int: %w", fi.ValueOf(e.Network.ID), err) } @@ -284,7 +284,7 @@ func (_ *LoadBalancer) RenderHetzner(t *hetzner.HetznerAPITarget, a, e, changes } else { var err error - loadbalancer, _, err := client.Get(ctx, strconv.Itoa(fi.ValueOf(a.ID))) + loadbalancer, _, err := client.Get(ctx, strconv.FormatInt(fi.ValueOf(a.ID), 10)) if err != nil { return err } diff --git a/upup/pkg/fi/cloudup/hetznertasks/network.go b/upup/pkg/fi/cloudup/hetznertasks/network.go index f63cf187cd980..f7f20bdc3862d 100644 --- a/upup/pkg/fi/cloudup/hetznertasks/network.go +++ b/upup/pkg/fi/cloudup/hetznertasks/network.go @@ -23,7 +23,7 @@ import ( "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" "k8s.io/kops/upup/pkg/fi/cloudup/terraform" @@ -72,7 +72,7 @@ func (v *Network) Find(c *fi.CloudupContext) (*Network, error) { matches := &Network{ Name: v.Name, Lifecycle: v.Lifecycle, - ID: fi.PtrTo(strconv.Itoa(network.ID)), + ID: fi.PtrTo(strconv.FormatInt(network.ID, 10)), } if v.ID == nil { @@ -151,7 +151,7 @@ func (_ *Network) RenderHetzner(t *hetzner.HetznerAPITarget, a, e, changes *Netw if err != nil { return err } - e.ID = fi.PtrTo(strconv.Itoa(network.ID)) + e.ID = fi.PtrTo(strconv.FormatInt(network.ID, 10)) } else { var err error diff --git a/upup/pkg/fi/cloudup/hetznertasks/servergroup.go b/upup/pkg/fi/cloudup/hetznertasks/servergroup.go index 4f327f8f13d57..4877b18a36df5 100644 --- a/upup/pkg/fi/cloudup/hetznertasks/servergroup.go +++ b/upup/pkg/fi/cloudup/hetznertasks/servergroup.go @@ -25,7 +25,7 @@ import ( "strconv" "strings" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" "k8s.io/kops/upup/pkg/fi/cloudup/terraform" @@ -206,7 +206,7 @@ func (_ *ServerGroup) RenderHetzner(t *hetzner.HetznerAPITarget, a, e, changes * } userDataHash := safeBytesHash(userDataBytes) - networkID, err := strconv.Atoi(fi.ValueOf(e.Network.ID)) + networkID, err := strconv.ParseInt(fi.ValueOf(e.Network.ID), 10, 64) if err != nil { return fmt.Errorf("failed to convert network ID %q to int: %w", fi.ValueOf(e.Network.ID), err) } diff --git a/upup/pkg/fi/cloudup/hetznertasks/sshkey.go b/upup/pkg/fi/cloudup/hetznertasks/sshkey.go index 5bc1776d46f58..ccb6dc4b5e651 100644 --- a/upup/pkg/fi/cloudup/hetznertasks/sshkey.go +++ b/upup/pkg/fi/cloudup/hetznertasks/sshkey.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/pkg/pki" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" @@ -35,7 +35,7 @@ type SSHKey struct { Name *string Lifecycle fi.Lifecycle - ID *int + ID *int64 PublicKey string Labels map[string]string @@ -44,7 +44,7 @@ type SSHKey struct { var _ fi.CompareWithID = &SSHKey{} func (v *SSHKey) CompareWithID() *string { - return fi.PtrTo(strconv.Itoa(fi.ValueOf(v.ID))) + return fi.PtrTo(strconv.FormatInt(fi.ValueOf(v.ID), 10)) } func (v *SSHKey) Find(c *fi.CloudupContext) (*SSHKey, error) { diff --git a/upup/pkg/fi/cloudup/hetznertasks/volume.go b/upup/pkg/fi/cloudup/hetznertasks/volume.go index 60228e3405d66..b2256e287e3f3 100644 --- a/upup/pkg/fi/cloudup/hetznertasks/volume.go +++ b/upup/pkg/fi/cloudup/hetznertasks/volume.go @@ -20,7 +20,7 @@ import ( "context" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/hetznercloud/hcloud-go/v2/hcloud" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/hetzner" "k8s.io/kops/upup/pkg/fi/cloudup/terraform" @@ -31,7 +31,7 @@ type Volume struct { Name *string Lifecycle fi.Lifecycle - ID *int + ID *int64 Location string Size int @@ -41,7 +41,7 @@ type Volume struct { var _ fi.CompareWithID = &Volume{} func (v *Volume) CompareWithID() *string { - return fi.PtrTo(strconv.Itoa(fi.ValueOf(v.ID))) + return fi.PtrTo(strconv.FormatInt(fi.ValueOf(v.ID), 10)) } func (v *Volume) Find(c *fi.CloudupContext) (*Volume, error) { @@ -119,7 +119,7 @@ func (_ *Volume) RenderHetzner(t *hetzner.HetznerAPITarget, a, e, changes *Volum } } else { - volume, _, err := client.Get(context.TODO(), strconv.Itoa(fi.ValueOf(a.ID))) + volume, _, err := client.Get(context.TODO(), strconv.FormatInt(fi.ValueOf(a.ID), 10)) if err != nil { return err } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go deleted file mode 100644 index da83c24ce7304..0000000000000 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/hcloud.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package hcloud is a library for the Hetzner Cloud API. -package hcloud - -// Version is the library's version following Semantic Versioning. -const Version = "1.59.2" // x-release-please-version diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/primary_ip.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/primary_ip.go deleted file mode 100644 index 3d51ea21f4dde..0000000000000 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/primary_ip.go +++ /dev/null @@ -1,422 +0,0 @@ -package hcloud - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net" - "net/url" - "strconv" - "time" - - "github.com/hetznercloud/hcloud-go/hcloud/schema" -) - -// PrimaryIP defines a Primary IP. -type PrimaryIP struct { - ID int - IP net.IP - Network *net.IPNet - Labels map[string]string - Name string - Type PrimaryIPType - Protection PrimaryIPProtection - DNSPtr map[string]string - AssigneeID int - AssigneeType string - AutoDelete bool - Blocked bool - Created time.Time - Datacenter *Datacenter -} - -// PrimaryIPProtection represents the protection level of a Primary IP. -type PrimaryIPProtection struct { - Delete bool -} - -// PrimaryIPDNSPTR contains reverse DNS information for a -// IPv4 or IPv6 Primary IP. -type PrimaryIPDNSPTR struct { - DNSPtr string - IP string -} - -// changeDNSPtr changes or resets the reverse DNS pointer for a IP address. -// Pass a nil ptr to reset the reverse DNS pointer to its default value. -func (p *PrimaryIP) changeDNSPtr(ctx context.Context, client *Client, ip net.IP, ptr *string) (*Action, *Response, error) { - reqBody := schema.PrimaryIPActionChangeDNSPtrRequest{ - IP: ip.String(), - DNSPtr: ptr, - } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/primary_ips/%d/actions/change_dns_ptr", p.ID) - req, err := client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody PrimaryIPChangeDNSPtrResult - resp, err := client.Do(req, &respBody) - if err != nil { - return nil, resp, err - } - return ActionFromSchema(respBody.Action), resp, nil -} - -// GetDNSPtrForIP searches for the dns assigned to the given IP address. -// It returns an error if there is no dns set for the given IP address. -func (p *PrimaryIP) GetDNSPtrForIP(ip net.IP) (string, error) { - dns, ok := p.DNSPtr[ip.String()] - if !ok { - return "", DNSNotFoundError{ip} - } - - return dns, nil -} - -// PrimaryIPType represents the type of Primary IP. -type PrimaryIPType string - -// PrimaryIPType Primary IP types. -const ( - PrimaryIPTypeIPv4 PrimaryIPType = "ipv4" - PrimaryIPTypeIPv6 PrimaryIPType = "ipv6" -) - -// PrimaryIPCreateOpts defines the request to -// create a Primary IP. -type PrimaryIPCreateOpts struct { - AssigneeID *int `json:"assignee_id,omitempty"` - AssigneeType string `json:"assignee_type"` - AutoDelete *bool `json:"auto_delete,omitempty"` - Datacenter string `json:"datacenter,omitempty"` - Labels map[string]string `json:"labels,omitempty"` - Name string `json:"name"` - Type PrimaryIPType `json:"type"` -} - -// PrimaryIPCreateResult defines the response -// when creating a Primary IP. -type PrimaryIPCreateResult struct { - PrimaryIP *PrimaryIP - Action *Action -} - -// PrimaryIPUpdateOpts defines the request to -// update a Primary IP. -type PrimaryIPUpdateOpts struct { - AutoDelete *bool `json:"auto_delete,omitempty"` - Labels *map[string]string `json:"labels,omitempty"` - Name string `json:"name,omitempty"` -} - -// PrimaryIPAssignOpts defines the request to -// assign a Primary IP to an assignee (usually a server). -type PrimaryIPAssignOpts struct { - ID int `json:"-"` - AssigneeID int `json:"assignee_id"` - AssigneeType string `json:"assignee_type"` -} - -// PrimaryIPAssignResult defines the response -// when assigning a Primary IP to a assignee. -type PrimaryIPAssignResult struct { - Action schema.Action `json:"action"` -} - -// PrimaryIPChangeDNSPtrOpts defines the request to -// change a DNS PTR entry from a Primary IP. -type PrimaryIPChangeDNSPtrOpts struct { - ID int `json:"-"` - DNSPtr string `json:"dns_ptr"` - IP string `json:"ip"` -} - -// PrimaryIPChangeDNSPtrResult defines the response -// when assigning a Primary IP to a assignee. -type PrimaryIPChangeDNSPtrResult struct { - Action schema.Action `json:"action"` -} - -// PrimaryIPChangeProtectionOpts defines the request to -// change protection configuration of a Primary IP. -type PrimaryIPChangeProtectionOpts struct { - ID int `json:"-"` - Delete bool `json:"delete"` -} - -// PrimaryIPChangeProtectionResult defines the response -// when changing a protection of a PrimaryIP. -type PrimaryIPChangeProtectionResult struct { - Action schema.Action `json:"action"` -} - -// PrimaryIPClient is a client for the Primary IP API. -type PrimaryIPClient struct { - client *Client - Action *ResourceActionClient -} - -// GetByID retrieves a Primary IP by its ID. If the Primary IP does not exist, nil is returned. -func (c *PrimaryIPClient) GetByID(ctx context.Context, id int) (*PrimaryIP, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/primary_ips/%d", id), nil) - if err != nil { - return nil, nil, err - } - - var body schema.PrimaryIPGetResult - resp, err := c.client.Do(req, &body) - if err != nil { - if IsError(err, ErrorCodeNotFound) { - return nil, resp, nil - } - return nil, nil, err - } - return PrimaryIPFromSchema(body.PrimaryIP), resp, nil -} - -// GetByIP retrieves a Primary IP by its IP Address. If the Primary IP does not exist, nil is returned. -func (c *PrimaryIPClient) GetByIP(ctx context.Context, ip string) (*PrimaryIP, *Response, error) { - if ip == "" { - return nil, nil, nil - } - primaryIPs, response, err := c.List(ctx, PrimaryIPListOpts{IP: ip}) - if len(primaryIPs) == 0 { - return nil, response, err - } - return primaryIPs[0], response, err -} - -// GetByName retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. -func (c *PrimaryIPClient) GetByName(ctx context.Context, name string) (*PrimaryIP, *Response, error) { - if name == "" { - return nil, nil, nil - } - primaryIPs, response, err := c.List(ctx, PrimaryIPListOpts{Name: name}) - if len(primaryIPs) == 0 { - return nil, response, err - } - return primaryIPs[0], response, err -} - -// Get retrieves a Primary IP by its ID if the input can be parsed as an integer, otherwise it -// retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. -func (c *PrimaryIPClient) Get(ctx context.Context, idOrName string) (*PrimaryIP, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) -} - -// PrimaryIPListOpts specifies options for listing Primary IPs. -type PrimaryIPListOpts struct { - ListOpts - Name string - IP string - Sort []string -} - -func (l PrimaryIPListOpts) values() url.Values { - vals := l.ListOpts.Values() - if l.Name != "" { - vals.Add("name", l.Name) - } - if l.IP != "" { - vals.Add("ip", l.IP) - } - for _, sort := range l.Sort { - vals.Add("sort", sort) - } - return vals -} - -// List returns a list of Primary IPs for a specific page. -// -// Please note that filters specified in opts are not taken into account -// when their value corresponds to their zero value or when they are empty. -func (c *PrimaryIPClient) List(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, *Response, error) { - path := "/primary_ips?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } - - var body schema.PrimaryIPListResult - resp, err := c.client.Do(req, &body) - if err != nil { - return nil, nil, err - } - primaryIPs := make([]*PrimaryIP, 0, len(body.PrimaryIPs)) - for _, s := range body.PrimaryIPs { - primaryIPs = append(primaryIPs, PrimaryIPFromSchema(s)) - } - return primaryIPs, resp, nil -} - -// All returns all Primary IPs. -func (c *PrimaryIPClient) All(ctx context.Context) ([]*PrimaryIP, error) { - return c.AllWithOpts(ctx, PrimaryIPListOpts{ListOpts: ListOpts{PerPage: 50}}) -} - -// AllWithOpts returns all Primary IPs for the given options. -func (c *PrimaryIPClient) AllWithOpts(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, error) { - allPrimaryIPs := []*PrimaryIP{} - - err := c.client.all(func(page int) (*Response, error) { - opts.Page = page - primaryIPs, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allPrimaryIPs = append(allPrimaryIPs, primaryIPs...) - return resp, nil - }) - if err != nil { - return nil, err - } - - return allPrimaryIPs, nil -} - -// Create creates a Primary IP. -func (c *PrimaryIPClient) Create(ctx context.Context, reqBody PrimaryIPCreateOpts) (*PrimaryIPCreateResult, *Response, error) { - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return &PrimaryIPCreateResult{}, nil, err - } - - req, err := c.client.NewRequest(ctx, "POST", "/primary_ips", bytes.NewReader(reqBodyData)) - if err != nil { - return &PrimaryIPCreateResult{}, nil, err - } - - var respBody schema.PrimaryIPCreateResponse - resp, err := c.client.Do(req, &respBody) - if err != nil { - return &PrimaryIPCreateResult{}, resp, err - } - var action *Action - if respBody.Action != nil { - action = ActionFromSchema(*respBody.Action) - } - primaryIP := PrimaryIPFromSchema(respBody.PrimaryIP) - return &PrimaryIPCreateResult{ - PrimaryIP: primaryIP, - Action: action, - }, resp, nil -} - -// Delete deletes a Primary IP. -func (c *PrimaryIPClient) Delete(ctx context.Context, primaryIP *PrimaryIP) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/primary_ips/%d", primaryIP.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) -} - -// Update updates a Primary IP. -func (c *PrimaryIPClient) Update(ctx context.Context, primaryIP *PrimaryIP, reqBody PrimaryIPUpdateOpts) (*PrimaryIP, *Response, error) { - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/primary_ips/%d", primaryIP.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.PrimaryIPUpdateResult - resp, err := c.client.Do(req, &respBody) - if err != nil { - return nil, resp, err - } - return PrimaryIPFromSchema(respBody.PrimaryIP), resp, nil -} - -// Assign a Primary IP to a resource. -func (c *PrimaryIPClient) Assign(ctx context.Context, opts PrimaryIPAssignOpts) (*Action, *Response, error) { - reqBodyData, err := json.Marshal(opts) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/primary_ips/%d/actions/assign", opts.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody PrimaryIPAssignResult - resp, err := c.client.Do(req, &respBody) - if err != nil { - return nil, resp, err - } - return ActionFromSchema(respBody.Action), resp, nil -} - -// Unassign a Primary IP from a resource. -func (c *PrimaryIPClient) Unassign(ctx context.Context, id int) (*Action, *Response, error) { - path := fmt.Sprintf("/primary_ips/%d/actions/unassign", id) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader([]byte{})) - if err != nil { - return nil, nil, err - } - - var respBody PrimaryIPAssignResult - resp, err := c.client.Do(req, &respBody) - if err != nil { - return nil, resp, err - } - return ActionFromSchema(respBody.Action), resp, nil -} - -// ChangeDNSPtr Change the reverse DNS from a Primary IP. -func (c *PrimaryIPClient) ChangeDNSPtr(ctx context.Context, opts PrimaryIPChangeDNSPtrOpts) (*Action, *Response, error) { - reqBodyData, err := json.Marshal(opts) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/primary_ips/%d/actions/change_dns_ptr", opts.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody PrimaryIPChangeDNSPtrResult - resp, err := c.client.Do(req, &respBody) - if err != nil { - return nil, resp, err - } - return ActionFromSchema(respBody.Action), resp, nil -} - -// ChangeProtection Changes the protection configuration of a Primary IP. -func (c *PrimaryIPClient) ChangeProtection(ctx context.Context, opts PrimaryIPChangeProtectionOpts) (*Action, *Response, error) { - reqBodyData, err := json.Marshal(opts) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/primary_ips/%d/actions/change_protection", opts.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody PrimaryIPChangeProtectionResult - resp, err := c.client.Do(req, &respBody) - if err != nil { - return nil, resp, err - } - return ActionFromSchema(respBody.Action), resp, nil -} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go deleted file mode 100644 index 8b8ffd0f78715..0000000000000 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema.go +++ /dev/null @@ -1,1297 +0,0 @@ -package hcloud - -import ( - "fmt" - "net" - "strconv" - "time" - - "github.com/hetznercloud/hcloud-go/hcloud/schema" -) - -// This file provides converter functions to convert models in the -// schema package to models in the hcloud package and vice versa. - -// ActionFromSchema converts a schema.Action to an Action. -func ActionFromSchema(s schema.Action) *Action { - action := &Action{ - ID: s.ID, - Status: ActionStatus(s.Status), - Command: s.Command, - Progress: s.Progress, - Started: s.Started, - Resources: []*ActionResource{}, - } - if s.Finished != nil { - action.Finished = *s.Finished - } - if s.Error != nil { - action.ErrorCode = s.Error.Code - action.ErrorMessage = s.Error.Message - } - for _, r := range s.Resources { - action.Resources = append(action.Resources, &ActionResource{ - ID: r.ID, - Type: ActionResourceType(r.Type), - }) - } - return action -} - -// ActionsFromSchema converts a slice of schema.Action to a slice of Action. -func ActionsFromSchema(s []schema.Action) []*Action { - actions := make([]*Action, len(s)) - for i, a := range s { - actions[i] = ActionFromSchema(a) - } - return actions -} - -// FloatingIPFromSchema converts a schema.FloatingIP to a FloatingIP. -func FloatingIPFromSchema(s schema.FloatingIP) *FloatingIP { - f := &FloatingIP{ - ID: s.ID, - Type: FloatingIPType(s.Type), - HomeLocation: LocationFromSchema(s.HomeLocation), - Created: s.Created, - Blocked: s.Blocked, - Protection: FloatingIPProtection{ - Delete: s.Protection.Delete, - }, - Name: s.Name, - } - if s.Description != nil { - f.Description = *s.Description - } - if s.Server != nil { - f.Server = &Server{ID: *s.Server} - } - if f.Type == FloatingIPTypeIPv4 { - f.IP = net.ParseIP(s.IP) - } else { - f.IP, f.Network, _ = net.ParseCIDR(s.IP) - } - f.DNSPtr = map[string]string{} - for _, entry := range s.DNSPtr { - f.DNSPtr[entry.IP] = entry.DNSPtr - } - f.Labels = map[string]string{} - for key, value := range s.Labels { - f.Labels[key] = value - } - return f -} - -// PrimaryIPFromSchema converts a schema.PrimaryIP to a PrimaryIP. -func PrimaryIPFromSchema(s schema.PrimaryIP) *PrimaryIP { - f := &PrimaryIP{ - ID: s.ID, - Type: PrimaryIPType(s.Type), - AutoDelete: s.AutoDelete, - - Created: s.Created, - Blocked: s.Blocked, - Protection: PrimaryIPProtection{ - Delete: s.Protection.Delete, - }, - Name: s.Name, - AssigneeType: s.AssigneeType, - AssigneeID: s.AssigneeID, - Datacenter: DatacenterFromSchema(s.Datacenter), - } - - if f.Type == PrimaryIPTypeIPv4 { - f.IP = net.ParseIP(s.IP) - } else { - f.IP, f.Network, _ = net.ParseCIDR(s.IP) - } - f.DNSPtr = map[string]string{} - for _, entry := range s.DNSPtr { - f.DNSPtr[entry.IP] = entry.DNSPtr - } - f.Labels = map[string]string{} - for key, value := range s.Labels { - f.Labels[key] = value - } - return f -} - -// ISOFromSchema converts a schema.ISO to an ISO. -func ISOFromSchema(s schema.ISO) *ISO { - iso := &ISO{ - ID: s.ID, - Name: s.Name, - Description: s.Description, - Type: ISOType(s.Type), - Deprecated: s.Deprecated, - DeprecatableResource: DeprecatableResource{ - DeprecationFromSchema(s.Deprecation), - }, - } - if s.Architecture != nil { - iso.Architecture = Ptr(Architecture(*s.Architecture)) - } - return iso -} - -// LocationFromSchema converts a schema.Location to a Location. -func LocationFromSchema(s schema.Location) *Location { - return &Location{ - ID: s.ID, - Name: s.Name, - Description: s.Description, - Country: s.Country, - City: s.City, - Latitude: s.Latitude, - Longitude: s.Longitude, - NetworkZone: NetworkZone(s.NetworkZone), - } -} - -// DatacenterFromSchema converts a schema.Datacenter to a Datacenter. -func DatacenterFromSchema(s schema.Datacenter) *Datacenter { - d := &Datacenter{ - ID: s.ID, - Name: s.Name, - Description: s.Description, - Location: LocationFromSchema(s.Location), - ServerTypes: DatacenterServerTypes{ - Available: []*ServerType{}, - Supported: []*ServerType{}, - }, - } - for _, t := range s.ServerTypes.Available { - d.ServerTypes.Available = append(d.ServerTypes.Available, &ServerType{ID: t}) - } - for _, t := range s.ServerTypes.Supported { - d.ServerTypes.Supported = append(d.ServerTypes.Supported, &ServerType{ID: t}) - } - return d -} - -// ServerFromSchema converts a schema.Server to a Server. -func ServerFromSchema(s schema.Server) *Server { - server := &Server{ - ID: s.ID, - Name: s.Name, - Status: ServerStatus(s.Status), - Created: s.Created, - PublicNet: ServerPublicNetFromSchema(s.PublicNet), - ServerType: ServerTypeFromSchema(s.ServerType), - IncludedTraffic: s.IncludedTraffic, - RescueEnabled: s.RescueEnabled, - Datacenter: DatacenterFromSchema(s.Datacenter), - Locked: s.Locked, - PrimaryDiskSize: s.PrimaryDiskSize, - Protection: ServerProtection{ - Delete: s.Protection.Delete, - Rebuild: s.Protection.Rebuild, - }, - } - if s.Image != nil { - server.Image = ImageFromSchema(*s.Image) - } - if s.BackupWindow != nil { - server.BackupWindow = *s.BackupWindow - } - if s.OutgoingTraffic != nil { - server.OutgoingTraffic = *s.OutgoingTraffic - } - if s.IngoingTraffic != nil { - server.IngoingTraffic = *s.IngoingTraffic - } - if s.ISO != nil { - server.ISO = ISOFromSchema(*s.ISO) - } - server.Labels = map[string]string{} - for key, value := range s.Labels { - server.Labels[key] = value - } - for _, id := range s.Volumes { - server.Volumes = append(server.Volumes, &Volume{ID: id}) - } - for _, privNet := range s.PrivateNet { - server.PrivateNet = append(server.PrivateNet, ServerPrivateNetFromSchema(privNet)) - } - if s.PlacementGroup != nil { - server.PlacementGroup = PlacementGroupFromSchema(*s.PlacementGroup) - } - return server -} - -// ServerPublicNetFromSchema converts a schema.ServerPublicNet to a ServerPublicNet. -func ServerPublicNetFromSchema(s schema.ServerPublicNet) ServerPublicNet { - publicNet := ServerPublicNet{ - IPv4: ServerPublicNetIPv4FromSchema(s.IPv4), - IPv6: ServerPublicNetIPv6FromSchema(s.IPv6), - } - for _, id := range s.FloatingIPs { - publicNet.FloatingIPs = append(publicNet.FloatingIPs, &FloatingIP{ID: id}) - } - for _, fw := range s.Firewalls { - publicNet.Firewalls = append(publicNet.Firewalls, - &ServerFirewallStatus{ - Firewall: Firewall{ID: fw.ID}, - Status: FirewallStatus(fw.Status)}, - ) - } - return publicNet -} - -// ServerPublicNetIPv4FromSchema converts a schema.ServerPublicNetIPv4 to -// a ServerPublicNetIPv4. -func ServerPublicNetIPv4FromSchema(s schema.ServerPublicNetIPv4) ServerPublicNetIPv4 { - return ServerPublicNetIPv4{ - ID: s.ID, - IP: net.ParseIP(s.IP), - Blocked: s.Blocked, - DNSPtr: s.DNSPtr, - } -} - -// ServerPublicNetIPv6FromSchema converts a schema.ServerPublicNetIPv6 to -// a ServerPublicNetIPv6. -func ServerPublicNetIPv6FromSchema(s schema.ServerPublicNetIPv6) ServerPublicNetIPv6 { - ipv6 := ServerPublicNetIPv6{ - ID: s.ID, - Blocked: s.Blocked, - DNSPtr: map[string]string{}, - } - ipv6.IP, ipv6.Network, _ = net.ParseCIDR(s.IP) - - for _, dnsPtr := range s.DNSPtr { - ipv6.DNSPtr[dnsPtr.IP] = dnsPtr.DNSPtr - } - return ipv6 -} - -// ServerPrivateNetFromSchema converts a schema.ServerPrivateNet to a ServerPrivateNet. -func ServerPrivateNetFromSchema(s schema.ServerPrivateNet) ServerPrivateNet { - n := ServerPrivateNet{ - Network: &Network{ID: s.Network}, - IP: net.ParseIP(s.IP), - MACAddress: s.MACAddress, - } - for _, ip := range s.AliasIPs { - n.Aliases = append(n.Aliases, net.ParseIP(ip)) - } - return n -} - -// ServerTypeFromSchema converts a schema.ServerType to a ServerType. -func ServerTypeFromSchema(s schema.ServerType) *ServerType { - st := &ServerType{ - ID: s.ID, - Name: s.Name, - Description: s.Description, - Cores: s.Cores, - Memory: s.Memory, - Disk: s.Disk, - StorageType: StorageType(s.StorageType), - CPUType: CPUType(s.CPUType), - Architecture: Architecture(s.Architecture), - IncludedTraffic: s.IncludedTraffic, // nolint:staticcheck // Field is deprecated, but we still need to map it as long as it is available - DeprecatableResource: DeprecatableResource{ - DeprecationFromSchema(s.Deprecation), - }, - } - for _, price := range s.Prices { - st.Pricings = append(st.Pricings, ServerTypeLocationPricing{ - Location: &Location{Name: price.Location}, - Hourly: Price{ - Net: price.PriceHourly.Net, - Gross: price.PriceHourly.Gross, - }, - Monthly: Price{ - Net: price.PriceMonthly.Net, - Gross: price.PriceMonthly.Gross, - }, - IncludedTraffic: price.IncludedTraffic, - PerTBTraffic: Price{ - Net: price.PricePerTBTraffic.Net, - Gross: price.PricePerTBTraffic.Gross, - }, - }) - } - - return st -} - -// SSHKeyFromSchema converts a schema.SSHKey to a SSHKey. -func SSHKeyFromSchema(s schema.SSHKey) *SSHKey { - sshKey := &SSHKey{ - ID: s.ID, - Name: s.Name, - Fingerprint: s.Fingerprint, - PublicKey: s.PublicKey, - Created: s.Created, - } - sshKey.Labels = map[string]string{} - for key, value := range s.Labels { - sshKey.Labels[key] = value - } - return sshKey -} - -// ImageFromSchema converts a schema.Image to an Image. -func ImageFromSchema(s schema.Image) *Image { - i := &Image{ - ID: s.ID, - Type: ImageType(s.Type), - Status: ImageStatus(s.Status), - Description: s.Description, - DiskSize: s.DiskSize, - Created: s.Created, - RapidDeploy: s.RapidDeploy, - OSFlavor: s.OSFlavor, - Architecture: Architecture(s.Architecture), - Protection: ImageProtection{ - Delete: s.Protection.Delete, - }, - Deprecated: s.Deprecated, - Deleted: s.Deleted, - } - if s.Name != nil { - i.Name = *s.Name - } - if s.ImageSize != nil { - i.ImageSize = *s.ImageSize - } - if s.OSVersion != nil { - i.OSVersion = *s.OSVersion - } - if s.CreatedFrom != nil { - i.CreatedFrom = &Server{ - ID: s.CreatedFrom.ID, - Name: s.CreatedFrom.Name, - } - } - if s.BoundTo != nil { - i.BoundTo = &Server{ - ID: *s.BoundTo, - } - } - i.Labels = map[string]string{} - for key, value := range s.Labels { - i.Labels[key] = value - } - return i -} - -// VolumeFromSchema converts a schema.Volume to a Volume. -func VolumeFromSchema(s schema.Volume) *Volume { - v := &Volume{ - ID: s.ID, - Name: s.Name, - Location: LocationFromSchema(s.Location), - Size: s.Size, - Format: s.Format, - Status: VolumeStatus(s.Status), - LinuxDevice: s.LinuxDevice, - Protection: VolumeProtection{ - Delete: s.Protection.Delete, - }, - Created: s.Created, - } - if s.Server != nil { - v.Server = &Server{ID: *s.Server} - } - v.Labels = map[string]string{} - for key, value := range s.Labels { - v.Labels[key] = value - } - return v -} - -// NetworkFromSchema converts a schema.Network to a Network. -func NetworkFromSchema(s schema.Network) *Network { - n := &Network{ - ID: s.ID, - Name: s.Name, - Created: s.Created, - Protection: NetworkProtection{ - Delete: s.Protection.Delete, - }, - Labels: map[string]string{}, - ExposeRoutesToVSwitch: s.ExposeRoutesToVSwitch, - } - - _, n.IPRange, _ = net.ParseCIDR(s.IPRange) - - for _, subnet := range s.Subnets { - n.Subnets = append(n.Subnets, NetworkSubnetFromSchema(subnet)) - } - for _, route := range s.Routes { - n.Routes = append(n.Routes, NetworkRouteFromSchema(route)) - } - for _, serverID := range s.Servers { - n.Servers = append(n.Servers, &Server{ID: serverID}) - } - for key, value := range s.Labels { - n.Labels[key] = value - } - - return n -} - -// NetworkSubnetFromSchema converts a schema.NetworkSubnet to a NetworkSubnet. -func NetworkSubnetFromSchema(s schema.NetworkSubnet) NetworkSubnet { - sn := NetworkSubnet{ - Type: NetworkSubnetType(s.Type), - NetworkZone: NetworkZone(s.NetworkZone), - Gateway: net.ParseIP(s.Gateway), - VSwitchID: s.VSwitchID, - } - _, sn.IPRange, _ = net.ParseCIDR(s.IPRange) - return sn -} - -// NetworkRouteFromSchema converts a schema.NetworkRoute to a NetworkRoute. -func NetworkRouteFromSchema(s schema.NetworkRoute) NetworkRoute { - r := NetworkRoute{ - Gateway: net.ParseIP(s.Gateway), - } - _, r.Destination, _ = net.ParseCIDR(s.Destination) - return r -} - -// LoadBalancerTypeFromSchema converts a schema.LoadBalancerType to a LoadBalancerType. -func LoadBalancerTypeFromSchema(s schema.LoadBalancerType) *LoadBalancerType { - lt := &LoadBalancerType{ - ID: s.ID, - Name: s.Name, - Description: s.Description, - MaxConnections: s.MaxConnections, - MaxServices: s.MaxServices, - MaxTargets: s.MaxTargets, - MaxAssignedCertificates: s.MaxAssignedCertificates, - } - for _, price := range s.Prices { - lt.Pricings = append(lt.Pricings, LoadBalancerTypeLocationPricing{ - Location: &Location{Name: price.Location}, - Hourly: Price{ - Net: price.PriceHourly.Net, - Gross: price.PriceHourly.Gross, - }, - Monthly: Price{ - Net: price.PriceMonthly.Net, - Gross: price.PriceMonthly.Gross, - }, - IncludedTraffic: price.IncludedTraffic, - PerTBTraffic: Price{ - Net: price.PricePerTBTraffic.Net, - Gross: price.PricePerTBTraffic.Gross, - }, - }) - } - return lt -} - -// LoadBalancerFromSchema converts a schema.LoadBalancer to a LoadBalancer. -func LoadBalancerFromSchema(s schema.LoadBalancer) *LoadBalancer { - l := &LoadBalancer{ - ID: s.ID, - Name: s.Name, - PublicNet: LoadBalancerPublicNet{ - Enabled: s.PublicNet.Enabled, - IPv4: LoadBalancerPublicNetIPv4{ - IP: net.ParseIP(s.PublicNet.IPv4.IP), - DNSPtr: s.PublicNet.IPv4.DNSPtr, - }, - IPv6: LoadBalancerPublicNetIPv6{ - IP: net.ParseIP(s.PublicNet.IPv6.IP), - DNSPtr: s.PublicNet.IPv6.DNSPtr, - }, - }, - Location: LocationFromSchema(s.Location), - LoadBalancerType: LoadBalancerTypeFromSchema(s.LoadBalancerType), - Algorithm: LoadBalancerAlgorithm{Type: LoadBalancerAlgorithmType(s.Algorithm.Type)}, - Protection: LoadBalancerProtection{ - Delete: s.Protection.Delete, - }, - Labels: map[string]string{}, - Created: s.Created, - IncludedTraffic: s.IncludedTraffic, - } - for _, privateNet := range s.PrivateNet { - l.PrivateNet = append(l.PrivateNet, LoadBalancerPrivateNet{ - Network: &Network{ID: privateNet.Network}, - IP: net.ParseIP(privateNet.IP), - }) - } - if s.OutgoingTraffic != nil { - l.OutgoingTraffic = *s.OutgoingTraffic - } - if s.IngoingTraffic != nil { - l.IngoingTraffic = *s.IngoingTraffic - } - for _, service := range s.Services { - l.Services = append(l.Services, LoadBalancerServiceFromSchema(service)) - } - for _, target := range s.Targets { - l.Targets = append(l.Targets, LoadBalancerTargetFromSchema(target)) - } - for key, value := range s.Labels { - l.Labels[key] = value - } - return l -} - -// LoadBalancerServiceFromSchema converts a schema.LoadBalancerService to a LoadBalancerService. -func LoadBalancerServiceFromSchema(s schema.LoadBalancerService) LoadBalancerService { - ls := LoadBalancerService{ - Protocol: LoadBalancerServiceProtocol(s.Protocol), - ListenPort: s.ListenPort, - DestinationPort: s.DestinationPort, - Proxyprotocol: s.Proxyprotocol, - HealthCheck: LoadBalancerServiceHealthCheckFromSchema(s.HealthCheck), - } - if s.HTTP != nil { - ls.HTTP = LoadBalancerServiceHTTP{ - CookieName: s.HTTP.CookieName, - CookieLifetime: time.Duration(s.HTTP.CookieLifetime) * time.Second, - RedirectHTTP: s.HTTP.RedirectHTTP, - StickySessions: s.HTTP.StickySessions, - } - for _, certificateID := range s.HTTP.Certificates { - ls.HTTP.Certificates = append(ls.HTTP.Certificates, &Certificate{ID: certificateID}) - } - } - return ls -} - -// LoadBalancerServiceHealthCheckFromSchema converts a schema.LoadBalancerServiceHealthCheck to a LoadBalancerServiceHealthCheck. -func LoadBalancerServiceHealthCheckFromSchema(s *schema.LoadBalancerServiceHealthCheck) LoadBalancerServiceHealthCheck { - lsh := LoadBalancerServiceHealthCheck{ - Protocol: LoadBalancerServiceProtocol(s.Protocol), - Port: s.Port, - Interval: time.Duration(s.Interval) * time.Second, - Retries: s.Retries, - Timeout: time.Duration(s.Timeout) * time.Second, - } - if s.HTTP != nil { - lsh.HTTP = &LoadBalancerServiceHealthCheckHTTP{ - Domain: s.HTTP.Domain, - Path: s.HTTP.Path, - Response: s.HTTP.Response, - StatusCodes: s.HTTP.StatusCodes, - TLS: s.HTTP.TLS, - } - } - return lsh -} - -// LoadBalancerTargetFromSchema converts a schema.LoadBalancerTarget to a LoadBalancerTarget. -func LoadBalancerTargetFromSchema(s schema.LoadBalancerTarget) LoadBalancerTarget { - lt := LoadBalancerTarget{ - Type: LoadBalancerTargetType(s.Type), - UsePrivateIP: s.UsePrivateIP, - } - if s.Server != nil { - lt.Server = &LoadBalancerTargetServer{ - Server: &Server{ID: s.Server.ID}, - } - } - if s.LabelSelector != nil { - lt.LabelSelector = &LoadBalancerTargetLabelSelector{ - Selector: s.LabelSelector.Selector, - } - } - if s.IP != nil { - lt.IP = &LoadBalancerTargetIP{IP: s.IP.IP} - } - - for _, healthStatus := range s.HealthStatus { - lt.HealthStatus = append(lt.HealthStatus, LoadBalancerTargetHealthStatusFromSchema(healthStatus)) - } - for _, target := range s.Targets { - lt.Targets = append(lt.Targets, LoadBalancerTargetFromSchema(target)) - } - return lt -} - -// LoadBalancerTargetHealthStatusFromSchema converts a schema.LoadBalancerTarget to a LoadBalancerTarget. -func LoadBalancerTargetHealthStatusFromSchema(s schema.LoadBalancerTargetHealthStatus) LoadBalancerTargetHealthStatus { - return LoadBalancerTargetHealthStatus{ - ListenPort: s.ListenPort, - Status: LoadBalancerTargetHealthStatusStatus(s.Status), - } -} - -// CertificateFromSchema converts a schema.Certificate to a Certificate. -func CertificateFromSchema(s schema.Certificate) *Certificate { - c := &Certificate{ - ID: s.ID, - Name: s.Name, - Type: CertificateType(s.Type), - Certificate: s.Certificate, - Created: s.Created, - NotValidBefore: s.NotValidBefore, - NotValidAfter: s.NotValidAfter, - DomainNames: s.DomainNames, - Fingerprint: s.Fingerprint, - } - if s.Status != nil { - c.Status = &CertificateStatus{ - Issuance: CertificateStatusType(s.Status.Issuance), - Renewal: CertificateStatusType(s.Status.Renewal), - } - if s.Status.Error != nil { - certErr := ErrorFromSchema(*s.Status.Error) - c.Status.Error = &certErr - } - } - if len(s.Labels) > 0 { - c.Labels = s.Labels - } - if len(s.UsedBy) > 0 { - c.UsedBy = make([]CertificateUsedByRef, len(s.UsedBy)) - for i, ref := range s.UsedBy { - c.UsedBy[i] = CertificateUsedByRef{ID: ref.ID, Type: CertificateUsedByRefType(ref.Type)} - } - } - - return c -} - -// PaginationFromSchema converts a schema.MetaPagination to a Pagination. -func PaginationFromSchema(s schema.MetaPagination) Pagination { - return Pagination{ - Page: s.Page, - PerPage: s.PerPage, - PreviousPage: s.PreviousPage, - NextPage: s.NextPage, - LastPage: s.LastPage, - TotalEntries: s.TotalEntries, - } -} - -// ErrorFromSchema converts a schema.Error to an Error. -func ErrorFromSchema(s schema.Error) Error { - e := Error{ - Code: ErrorCode(s.Code), - Message: s.Message, - } - - if d, ok := s.Details.(schema.ErrorDetailsInvalidInput); ok { - details := ErrorDetailsInvalidInput{ - Fields: []ErrorDetailsInvalidInputField{}, - } - for _, field := range d.Fields { - details.Fields = append(details.Fields, ErrorDetailsInvalidInputField{ - Name: field.Name, - Messages: field.Messages, - }) - } - e.Details = details - } - return e -} - -// PricingFromSchema converts a schema.Pricing to a Pricing. -func PricingFromSchema(s schema.Pricing) Pricing { - p := Pricing{ - Image: ImagePricing{ - PerGBMonth: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: s.Image.PricePerGBMonth.Net, - Gross: s.Image.PricePerGBMonth.Gross, - }, - }, - FloatingIP: FloatingIPPricing{ - Monthly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: s.FloatingIP.PriceMonthly.Net, - Gross: s.FloatingIP.PriceMonthly.Gross, - }, - }, - Traffic: TrafficPricing{ - PerTB: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: s.Traffic.PricePerTB.Net, // nolint:staticcheck // Field is deprecated, but we still need to map it as long as it is available - Gross: s.Traffic.PricePerTB.Gross, // nolint:staticcheck // Field is deprecated, but we still need to map it as long as it is available - }, - }, - ServerBackup: ServerBackupPricing{ - Percentage: s.ServerBackup.Percentage, - }, - Volume: VolumePricing{ - PerGBMonthly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: s.Volume.PricePerGBPerMonth.Net, - Gross: s.Volume.PricePerGBPerMonth.Gross, - }, - }, - } - for _, floatingIPType := range s.FloatingIPs { - var pricings []FloatingIPTypeLocationPricing - for _, price := range floatingIPType.Prices { - p := FloatingIPTypeLocationPricing{ - Location: &Location{Name: price.Location}, - Monthly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PriceMonthly.Net, - Gross: price.PriceMonthly.Gross, - }, - } - pricings = append(pricings, p) - } - p.FloatingIPs = append(p.FloatingIPs, FloatingIPTypePricing{Type: FloatingIPType(floatingIPType.Type), Pricings: pricings}) - } - for _, primaryIPType := range s.PrimaryIPs { - var pricings []PrimaryIPTypePricing - for _, price := range primaryIPType.Prices { - p := PrimaryIPTypePricing{ - Location: price.Location, - Monthly: PrimaryIPPrice{ - Net: price.PriceMonthly.Net, - Gross: price.PriceMonthly.Gross, - }, - Hourly: PrimaryIPPrice{ - Net: price.PriceHourly.Net, - Gross: price.PriceHourly.Gross, - }, - } - pricings = append(pricings, p) - } - p.PrimaryIPs = append(p.PrimaryIPs, PrimaryIPPricing{Type: primaryIPType.Type, Pricings: pricings}) - } - for _, serverType := range s.ServerTypes { - var pricings []ServerTypeLocationPricing - for _, price := range serverType.Prices { - pricings = append(pricings, ServerTypeLocationPricing{ - Location: &Location{Name: price.Location}, - Hourly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PriceHourly.Net, - Gross: price.PriceHourly.Gross, - }, - Monthly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PriceMonthly.Net, - Gross: price.PriceMonthly.Gross, - }, - IncludedTraffic: price.IncludedTraffic, - PerTBTraffic: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PricePerTBTraffic.Net, - Gross: price.PricePerTBTraffic.Gross, - }, - }) - } - p.ServerTypes = append(p.ServerTypes, ServerTypePricing{ - ServerType: &ServerType{ - ID: serverType.ID, - Name: serverType.Name, - }, - Pricings: pricings, - }) - } - for _, loadBalancerType := range s.LoadBalancerTypes { - var pricings []LoadBalancerTypeLocationPricing - for _, price := range loadBalancerType.Prices { - pricings = append(pricings, LoadBalancerTypeLocationPricing{ - Location: &Location{Name: price.Location}, - Hourly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PriceHourly.Net, - Gross: price.PriceHourly.Gross, - }, - Monthly: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PriceMonthly.Net, - Gross: price.PriceMonthly.Gross, - }, - IncludedTraffic: price.IncludedTraffic, - PerTBTraffic: Price{ - Currency: s.Currency, - VATRate: s.VATRate, - Net: price.PricePerTBTraffic.Net, - Gross: price.PricePerTBTraffic.Gross, - }, - }) - } - p.LoadBalancerTypes = append(p.LoadBalancerTypes, LoadBalancerTypePricing{ - LoadBalancerType: &LoadBalancerType{ - ID: loadBalancerType.ID, - Name: loadBalancerType.Name, - }, - Pricings: pricings, - }) - } - return p -} - -// FirewallFromSchema converts a schema.Firewall to a Firewall. -func FirewallFromSchema(s schema.Firewall) *Firewall { - f := &Firewall{ - ID: s.ID, - Name: s.Name, - Labels: map[string]string{}, - Created: s.Created, - } - for key, value := range s.Labels { - f.Labels[key] = value - } - for _, res := range s.AppliedTo { - r := FirewallResource{Type: FirewallResourceType(res.Type)} - switch r.Type { - case FirewallResourceTypeLabelSelector: - r.LabelSelector = &FirewallResourceLabelSelector{Selector: res.LabelSelector.Selector} - case FirewallResourceTypeServer: - r.Server = &FirewallResourceServer{ID: res.Server.ID} - } - f.AppliedTo = append(f.AppliedTo, r) - } - for _, rule := range s.Rules { - sourceIPs := []net.IPNet{} - for _, sourceIP := range rule.SourceIPs { - _, mask, err := net.ParseCIDR(sourceIP) - if err == nil && mask != nil { - sourceIPs = append(sourceIPs, *mask) - } - } - destinationIPs := []net.IPNet{} - for _, destinationIP := range rule.DestinationIPs { - _, mask, err := net.ParseCIDR(destinationIP) - if err == nil && mask != nil { - destinationIPs = append(destinationIPs, *mask) - } - } - f.Rules = append(f.Rules, FirewallRule{ - Direction: FirewallRuleDirection(rule.Direction), - SourceIPs: sourceIPs, - DestinationIPs: destinationIPs, - Protocol: FirewallRuleProtocol(rule.Protocol), - Port: rule.Port, - Description: rule.Description, - }) - } - return f -} - -// PlacementGroupFromSchema converts a schema.PlacementGroup to a PlacementGroup. -func PlacementGroupFromSchema(s schema.PlacementGroup) *PlacementGroup { - g := &PlacementGroup{ - ID: s.ID, - Name: s.Name, - Labels: s.Labels, - Created: s.Created, - Servers: s.Servers, - Type: PlacementGroupType(s.Type), - } - return g -} - -func placementGroupCreateOptsToSchema(opts PlacementGroupCreateOpts) schema.PlacementGroupCreateRequest { - req := schema.PlacementGroupCreateRequest{ - Name: opts.Name, - Type: string(opts.Type), - } - if opts.Labels != nil { - req.Labels = &opts.Labels - } - return req -} - -func loadBalancerCreateOptsToSchema(opts LoadBalancerCreateOpts) schema.LoadBalancerCreateRequest { - req := schema.LoadBalancerCreateRequest{ - Name: opts.Name, - PublicInterface: opts.PublicInterface, - } - if opts.Algorithm != nil { - req.Algorithm = &schema.LoadBalancerCreateRequestAlgorithm{ - Type: string(opts.Algorithm.Type), - } - } - if opts.LoadBalancerType.ID != 0 { - req.LoadBalancerType = opts.LoadBalancerType.ID - } else if opts.LoadBalancerType.Name != "" { - req.LoadBalancerType = opts.LoadBalancerType.Name - } - if opts.Location != nil { - if opts.Location.ID != 0 { - req.Location = Ptr(strconv.Itoa(opts.Location.ID)) - } else { - req.Location = Ptr(opts.Location.Name) - } - } - if opts.NetworkZone != "" { - req.NetworkZone = Ptr(string(opts.NetworkZone)) - } - if opts.Labels != nil { - req.Labels = &opts.Labels - } - if opts.Network != nil { - req.Network = Ptr(opts.Network.ID) - } - for _, target := range opts.Targets { - schemaTarget := schema.LoadBalancerCreateRequestTarget{ - UsePrivateIP: target.UsePrivateIP, - } - switch target.Type { - case LoadBalancerTargetTypeServer: - schemaTarget.Type = string(LoadBalancerTargetTypeServer) - schemaTarget.Server = &schema.LoadBalancerCreateRequestTargetServer{ID: target.Server.Server.ID} - case LoadBalancerTargetTypeLabelSelector: - schemaTarget.Type = string(LoadBalancerTargetTypeLabelSelector) - schemaTarget.LabelSelector = &schema.LoadBalancerCreateRequestTargetLabelSelector{Selector: target.LabelSelector.Selector} - case LoadBalancerTargetTypeIP: - schemaTarget.Type = string(LoadBalancerTargetTypeIP) - schemaTarget.IP = &schema.LoadBalancerCreateRequestTargetIP{IP: target.IP.IP} - } - req.Targets = append(req.Targets, schemaTarget) - } - for _, service := range opts.Services { - schemaService := schema.LoadBalancerCreateRequestService{ - Protocol: string(service.Protocol), - ListenPort: service.ListenPort, - DestinationPort: service.DestinationPort, - Proxyprotocol: service.Proxyprotocol, - } - if service.HTTP != nil { - schemaService.HTTP = &schema.LoadBalancerCreateRequestServiceHTTP{ - RedirectHTTP: service.HTTP.RedirectHTTP, - StickySessions: service.HTTP.StickySessions, - CookieName: service.HTTP.CookieName, - } - if service.HTTP.CookieLifetime != nil { - if sec := service.HTTP.CookieLifetime.Seconds(); sec != 0 { - schemaService.HTTP.CookieLifetime = Ptr(int(sec)) - } - } - if service.HTTP.Certificates != nil { - certificates := []int{} - for _, certificate := range service.HTTP.Certificates { - certificates = append(certificates, certificate.ID) - } - schemaService.HTTP.Certificates = &certificates - } - } - if service.HealthCheck != nil { - schemaHealthCheck := &schema.LoadBalancerCreateRequestServiceHealthCheck{ - Protocol: string(service.HealthCheck.Protocol), - Port: service.HealthCheck.Port, - Retries: service.HealthCheck.Retries, - } - if service.HealthCheck.Interval != nil { - schemaHealthCheck.Interval = Ptr(int(service.HealthCheck.Interval.Seconds())) - } - if service.HealthCheck.Timeout != nil { - schemaHealthCheck.Timeout = Ptr(int(service.HealthCheck.Timeout.Seconds())) - } - if service.HealthCheck.HTTP != nil { - schemaHealthCheckHTTP := &schema.LoadBalancerCreateRequestServiceHealthCheckHTTP{ - Domain: service.HealthCheck.HTTP.Domain, - Path: service.HealthCheck.HTTP.Path, - Response: service.HealthCheck.HTTP.Response, - TLS: service.HealthCheck.HTTP.TLS, - } - if service.HealthCheck.HTTP.StatusCodes != nil { - //nolint:gosec - schemaHealthCheckHTTP.StatusCodes = &service.HealthCheck.HTTP.StatusCodes - } - schemaHealthCheck.HTTP = schemaHealthCheckHTTP - } - schemaService.HealthCheck = schemaHealthCheck - } - req.Services = append(req.Services, schemaService) - } - return req -} - -func loadBalancerAddServiceOptsToSchema(opts LoadBalancerAddServiceOpts) schema.LoadBalancerActionAddServiceRequest { - req := schema.LoadBalancerActionAddServiceRequest{ - Protocol: string(opts.Protocol), - ListenPort: opts.ListenPort, - DestinationPort: opts.DestinationPort, - Proxyprotocol: opts.Proxyprotocol, - } - if opts.HTTP != nil { - req.HTTP = &schema.LoadBalancerActionAddServiceRequestHTTP{ - CookieName: opts.HTTP.CookieName, - RedirectHTTP: opts.HTTP.RedirectHTTP, - StickySessions: opts.HTTP.StickySessions, - } - if opts.HTTP.CookieLifetime != nil { - req.HTTP.CookieLifetime = Ptr(int(opts.HTTP.CookieLifetime.Seconds())) - } - if opts.HTTP.Certificates != nil { - certificates := []int{} - for _, certificate := range opts.HTTP.Certificates { - certificates = append(certificates, certificate.ID) - } - req.HTTP.Certificates = &certificates - } - } - if opts.HealthCheck != nil { - req.HealthCheck = &schema.LoadBalancerActionAddServiceRequestHealthCheck{ - Protocol: string(opts.HealthCheck.Protocol), - Port: opts.HealthCheck.Port, - Retries: opts.HealthCheck.Retries, - } - if opts.HealthCheck.Interval != nil { - req.HealthCheck.Interval = Ptr(int(opts.HealthCheck.Interval.Seconds())) - } - if opts.HealthCheck.Timeout != nil { - req.HealthCheck.Timeout = Ptr(int(opts.HealthCheck.Timeout.Seconds())) - } - if opts.HealthCheck.HTTP != nil { - req.HealthCheck.HTTP = &schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP{ - Domain: opts.HealthCheck.HTTP.Domain, - Path: opts.HealthCheck.HTTP.Path, - Response: opts.HealthCheck.HTTP.Response, - TLS: opts.HealthCheck.HTTP.TLS, - } - if opts.HealthCheck.HTTP.StatusCodes != nil { - req.HealthCheck.HTTP.StatusCodes = &opts.HealthCheck.HTTP.StatusCodes - } - } - } - return req -} - -func loadBalancerUpdateServiceOptsToSchema(opts LoadBalancerUpdateServiceOpts) schema.LoadBalancerActionUpdateServiceRequest { - req := schema.LoadBalancerActionUpdateServiceRequest{ - DestinationPort: opts.DestinationPort, - Proxyprotocol: opts.Proxyprotocol, - } - if opts.Protocol != "" { - req.Protocol = Ptr(string(opts.Protocol)) - } - if opts.HTTP != nil { - req.HTTP = &schema.LoadBalancerActionUpdateServiceRequestHTTP{ - CookieName: opts.HTTP.CookieName, - RedirectHTTP: opts.HTTP.RedirectHTTP, - StickySessions: opts.HTTP.StickySessions, - } - if opts.HTTP.CookieLifetime != nil { - req.HTTP.CookieLifetime = Ptr(int(opts.HTTP.CookieLifetime.Seconds())) - } - if opts.HTTP.Certificates != nil { - certificates := []int{} - for _, certificate := range opts.HTTP.Certificates { - certificates = append(certificates, certificate.ID) - } - req.HTTP.Certificates = &certificates - } - } - if opts.HealthCheck != nil { - req.HealthCheck = &schema.LoadBalancerActionUpdateServiceRequestHealthCheck{ - Port: opts.HealthCheck.Port, - Retries: opts.HealthCheck.Retries, - } - if opts.HealthCheck.Interval != nil { - req.HealthCheck.Interval = Ptr(int(opts.HealthCheck.Interval.Seconds())) - } - if opts.HealthCheck.Timeout != nil { - req.HealthCheck.Timeout = Ptr(int(opts.HealthCheck.Timeout.Seconds())) - } - if opts.HealthCheck.Protocol != "" { - req.HealthCheck.Protocol = Ptr(string(opts.HealthCheck.Protocol)) - } - if opts.HealthCheck.HTTP != nil { - req.HealthCheck.HTTP = &schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP{ - Domain: opts.HealthCheck.HTTP.Domain, - Path: opts.HealthCheck.HTTP.Path, - Response: opts.HealthCheck.HTTP.Response, - TLS: opts.HealthCheck.HTTP.TLS, - } - if opts.HealthCheck.HTTP.StatusCodes != nil { - req.HealthCheck.HTTP.StatusCodes = &opts.HealthCheck.HTTP.StatusCodes - } - } - } - return req -} - -func firewallCreateOptsToSchema(opts FirewallCreateOpts) schema.FirewallCreateRequest { - req := schema.FirewallCreateRequest{ - Name: opts.Name, - } - if opts.Labels != nil { - req.Labels = &opts.Labels - } - for _, rule := range opts.Rules { - schemaRule := schema.FirewallRuleRequest{ - Direction: string(rule.Direction), - Protocol: string(rule.Protocol), - Port: rule.Port, - Description: rule.Description, - } - switch rule.Direction { - case FirewallRuleDirectionOut: - schemaRule.DestinationIPs = make([]string, len(rule.DestinationIPs)) - for i, destinationIP := range rule.DestinationIPs { - schemaRule.DestinationIPs[i] = destinationIP.String() - } - case FirewallRuleDirectionIn: - schemaRule.SourceIPs = make([]string, len(rule.SourceIPs)) - for i, sourceIP := range rule.SourceIPs { - schemaRule.SourceIPs[i] = sourceIP.String() - } - } - req.Rules = append(req.Rules, schemaRule) - } - for _, res := range opts.ApplyTo { - schemaFirewallResource := schema.FirewallResource{ - Type: string(res.Type), - } - switch res.Type { - case FirewallResourceTypeServer: - schemaFirewallResource.Server = &schema.FirewallResourceServer{ - ID: res.Server.ID, - } - case FirewallResourceTypeLabelSelector: - schemaFirewallResource.LabelSelector = &schema.FirewallResourceLabelSelector{Selector: res.LabelSelector.Selector} - } - - req.ApplyTo = append(req.ApplyTo, schemaFirewallResource) - } - return req -} - -func firewallSetRulesOptsToSchema(opts FirewallSetRulesOpts) schema.FirewallActionSetRulesRequest { - req := schema.FirewallActionSetRulesRequest{Rules: []schema.FirewallRuleRequest{}} - for _, rule := range opts.Rules { - schemaRule := schema.FirewallRuleRequest{ - Direction: string(rule.Direction), - Protocol: string(rule.Protocol), - Port: rule.Port, - Description: rule.Description, - } - switch rule.Direction { - case FirewallRuleDirectionOut: - schemaRule.DestinationIPs = make([]string, len(rule.DestinationIPs)) - for i, destinationIP := range rule.DestinationIPs { - schemaRule.DestinationIPs[i] = destinationIP.String() - } - case FirewallRuleDirectionIn: - schemaRule.SourceIPs = make([]string, len(rule.SourceIPs)) - for i, sourceIP := range rule.SourceIPs { - schemaRule.SourceIPs[i] = sourceIP.String() - } - } - req.Rules = append(req.Rules, schemaRule) - } - return req -} - -func firewallResourceToSchema(resource FirewallResource) schema.FirewallResource { - s := schema.FirewallResource{ - Type: string(resource.Type), - } - switch resource.Type { - case FirewallResourceTypeLabelSelector: - s.LabelSelector = &schema.FirewallResourceLabelSelector{Selector: resource.LabelSelector.Selector} - case FirewallResourceTypeServer: - s.Server = &schema.FirewallResourceServer{ID: resource.Server.ID} - } - return s -} - -func serverMetricsFromSchema(s *schema.ServerGetMetricsResponse) (*ServerMetrics, error) { - ms := ServerMetrics{ - Start: s.Metrics.Start, - End: s.Metrics.End, - Step: s.Metrics.Step, - } - - timeSeries := make(map[string][]ServerMetricsValue) - for tsName, v := range s.Metrics.TimeSeries { - vals := make([]ServerMetricsValue, len(v.Values)) - - for i, rawVal := range v.Values { - var val ServerMetricsValue - - tup, ok := rawVal.([]interface{}) - if !ok { - return nil, fmt.Errorf("failed to convert value to tuple: %v", rawVal) - } - if len(tup) != 2 { - return nil, fmt.Errorf("invalid tuple size: %d: %v", len(tup), rawVal) - } - ts, ok := tup[0].(float64) - if !ok { - return nil, fmt.Errorf("convert to float64: %v", tup[0]) - } - val.Timestamp = ts - - v, ok := tup[1].(string) - if !ok { - return nil, fmt.Errorf("not a string: %v", tup[1]) - } - val.Value = v - vals[i] = val - } - - timeSeries[tsName] = vals - } - ms.TimeSeries = timeSeries - - return &ms, nil -} - -func loadBalancerMetricsFromSchema(s *schema.LoadBalancerGetMetricsResponse) (*LoadBalancerMetrics, error) { - ms := LoadBalancerMetrics{ - Start: s.Metrics.Start, - End: s.Metrics.End, - Step: s.Metrics.Step, - } - - timeSeries := make(map[string][]LoadBalancerMetricsValue) - for tsName, v := range s.Metrics.TimeSeries { - vals := make([]LoadBalancerMetricsValue, len(v.Values)) - - for i, rawVal := range v.Values { - var val LoadBalancerMetricsValue - - tup, ok := rawVal.([]interface{}) - if !ok { - return nil, fmt.Errorf("failed to convert value to tuple: %v", rawVal) - } - if len(tup) != 2 { - return nil, fmt.Errorf("invalid tuple size: %d: %v", len(tup), rawVal) - } - ts, ok := tup[0].(float64) - if !ok { - return nil, fmt.Errorf("convert to float64: %v", tup[0]) - } - val.Timestamp = ts - - v, ok := tup[1].(string) - if !ok { - return nil, fmt.Errorf("not a string: %v", tup[1]) - } - val.Value = v - vals[i] = val - } - - timeSeries[tsName] = vals - } - ms.TimeSeries = timeSeries - - return &ms, nil -} - -// DeprecationFromSchema converts a [schema.DeprecationInfo] to a [DeprecationInfo]. -func DeprecationFromSchema(s *schema.DeprecationInfo) *DeprecationInfo { - if s == nil { - return nil - } - - return &DeprecationInfo{ - Announced: s.Announced, - UnavailableAfter: s.UnavailableAfter, - } -} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/datacenter.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/datacenter.go deleted file mode 100644 index 3e8178e89a034..0000000000000 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/datacenter.go +++ /dev/null @@ -1,23 +0,0 @@ -package schema - -// Datacenter defines the schema of a datacenter. -type Datacenter struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Location Location `json:"location"` - ServerTypes struct { - Supported []int `json:"supported"` - Available []int `json:"available"` - } `json:"server_types"` -} - -// DatacenterGetResponse defines the schema of the response when retrieving a single datacenter. -type DatacenterGetResponse struct { - Datacenter Datacenter `json:"datacenter"` -} - -// DatacenterListResponse defines the schema of the response when listing datacenters. -type DatacenterListResponse struct { - Datacenters []Datacenter `json:"datacenters"` -} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/primary_ip.go b/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/primary_ip.go deleted file mode 100644 index f6c7229a2b4cd..0000000000000 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/primary_ip.go +++ /dev/null @@ -1,62 +0,0 @@ -package schema - -import "time" - -// PrimaryIP defines a Primary IP. -type PrimaryIP struct { - ID int `json:"id"` - IP string `json:"ip"` - Labels map[string]string `json:"labels"` - Name string `json:"name"` - Type string `json:"type"` - Protection PrimaryIPProtection `json:"protection"` - DNSPtr []PrimaryIPDNSPTR `json:"dns_ptr"` - AssigneeID int `json:"assignee_id"` - AssigneeType string `json:"assignee_type"` - AutoDelete bool `json:"auto_delete"` - Blocked bool `json:"blocked"` - Created time.Time `json:"created"` - Datacenter Datacenter `json:"datacenter"` -} - -// PrimaryIPProtection represents the protection level of a Primary IP. -type PrimaryIPProtection struct { - Delete bool `json:"delete"` -} - -// PrimaryIPDNSPTR contains reverse DNS information for a -// IPv4 or IPv6 Primary IP. -type PrimaryIPDNSPTR struct { - DNSPtr string `json:"dns_ptr"` - IP string `json:"ip"` -} - -// PrimaryIPCreateResponse defines the schema of the response -// when creating a Primary IP. -type PrimaryIPCreateResponse struct { - PrimaryIP PrimaryIP `json:"primary_ip"` - Action *Action `json:"action"` -} - -// PrimaryIPGetResult defines the response when retrieving a single Primary IP. -type PrimaryIPGetResult struct { - PrimaryIP PrimaryIP `json:"primary_ip"` -} - -// PrimaryIPListResult defines the response when listing Primary IPs. -type PrimaryIPListResult struct { - PrimaryIPs []PrimaryIP `json:"primary_ips"` -} - -// PrimaryIPUpdateResult defines the response -// when updating a Primary IP. -type PrimaryIPUpdateResult struct { - PrimaryIP PrimaryIP `json:"primary_ip"` -} - -// PrimaryIPActionChangeDNSPtrRequest defines the schema for the request to -// change a Primary IP's reverse DNS pointer. -type PrimaryIPActionChangeDNSPtrRequest struct { - IP string `json:"ip"` - DNSPtr *string `json:"dns_ptr"` -} diff --git a/vendor/github.com/hetznercloud/hcloud-go/LICENSE b/vendor/github.com/hetznercloud/hcloud-go/v2/LICENSE similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/LICENSE rename to vendor/github.com/hetznercloud/hcloud-go/v2/LICENSE diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action.go similarity index 71% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action.go index 9b5d65e1890de..0ea274fff972e 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action.go @@ -6,12 +6,13 @@ import ( "net/url" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Action represents an action in the Hetzner Cloud. type Action struct { - ID int + ID int64 Status ActionStatus Command string Progress int @@ -34,7 +35,7 @@ const ( // ActionResource references other resources from an action. type ActionResource struct { - ID int + ID int64 Type ActionResourceType } @@ -54,9 +55,21 @@ const ( type ActionError struct { Code string Message string + + action *Action +} + +// Action returns the [Action] that triggered the error if available. +func (e ActionError) Action() *Action { + return e.action } func (e ActionError) Error() string { + action := e.Action() + if action != nil { + // For easier debugging, the error string contains the Action ID. + return fmt.Sprintf("%s (%s, %d)", e.Message, e.Code, action.ID) + } return fmt.Sprintf("%s (%s)", e.Message, e.Code) } @@ -65,6 +78,7 @@ func (a *Action) Error() error { return ActionError{ Code: a.ErrorCode, Message: a.ErrorMessage, + action: a, } } return nil @@ -76,14 +90,14 @@ type ActionClient struct { } // GetByID retrieves an action by its ID. If the action does not exist, nil is returned. -func (c *ActionClient) GetByID(ctx context.Context, id int) (*Action, *Response, error) { +func (c *ActionClient) GetByID(ctx context.Context, id int64) (*Action, *Response, error) { return c.action.GetByID(ctx, id) } // ActionListOpts specifies options for listing actions. type ActionListOpts struct { ListOpts - ID []int + ID []int64 Status []ActionStatus Sort []string } @@ -111,11 +125,15 @@ func (c *ActionClient) List(ctx context.Context, opts ActionListOpts) ([]*Action } // All returns all actions. +// +// Deprecated: It is required to pass in a list of IDs since 30 January 2025. Please use [ActionClient.AllWithOpts] instead. func (c *ActionClient) All(ctx context.Context) ([]*Action, error) { return c.action.All(ctx, ActionListOpts{ListOpts: ListOpts{PerPage: 50}}) } // AllWithOpts returns all actions for the given options. +// +// It is required to set [ActionListOpts.ID]. Any other fields set in the opts are ignored. func (c *ActionClient) AllWithOpts(ctx context.Context, opts ActionListOpts) ([]*Action, error) { return c.action.All(ctx, opts) } @@ -135,21 +153,20 @@ func (c *ResourceActionClient) getBaseURL() string { } // GetByID retrieves an action by its ID. If the action does not exist, nil is returned. -func (c *ResourceActionClient) GetByID(ctx context.Context, id int) (*Action, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("%s/actions/%d", c.getBaseURL(), id), nil) - if err != nil { - return nil, nil, err - } +func (c *ResourceActionClient) GetByID(ctx context.Context, id int64) (*Action, *Response, error) { + opPath := c.getBaseURL() + "/actions/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.ActionGetResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, id) + + respBody, resp, err := getRequest[schema.ActionGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return ActionFromSchema(body.Action), resp, nil + return ActionFromSchema(respBody.Action), resp, nil } // List returns a list of actions for a specific page. @@ -157,44 +174,23 @@ func (c *ResourceActionClient) GetByID(ctx context.Context, id int) (*Action, *R // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *ResourceActionClient) List(ctx context.Context, opts ActionListOpts) ([]*Action, *Response, error) { - req, err := c.client.NewRequest( - ctx, - "GET", - fmt.Sprintf("%s/actions?%s", c.getBaseURL(), opts.values().Encode()), - nil, - ) - if err != nil { - return nil, nil, err - } + opPath := c.getBaseURL() + "/actions?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.ActionListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ActionListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - actions := make([]*Action, 0, len(body.Actions)) - for _, i := range body.Actions { - actions = append(actions, ActionFromSchema(i)) + return nil, resp, err } - return actions, resp, nil + + return allFromSchemaFunc(respBody.Actions, ActionFromSchema), resp, nil } // All returns all actions for the given options. func (c *ResourceActionClient) All(ctx context.Context, opts ActionListOpts) ([]*Action, error) { - allActions := []*Action{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Action, *Response, error) { opts.Page = page - actions, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allActions = append(allActions, actions...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allActions, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action_waiter.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action_waiter.go similarity index 80% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/action_waiter.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action_waiter.go index 18f32c80bc266..50f5bba772340 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action_waiter.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action_waiter.go @@ -16,7 +16,7 @@ type ActionWaiter interface { var _ ActionWaiter = (*ActionClient)(nil) // WaitForFunc waits until all actions are completed by polling the API at the interval -// defined by [WithPollBackoffFunc]. An action is considered as complete when its status is +// defined by [WithPollOpts]. An action is considered as complete when its status is // either [ActionStatusSuccess] or [ActionStatusError]. // // The handleUpdate callback is called every time an action is updated. @@ -24,7 +24,7 @@ func (c *ActionClient) WaitForFunc(ctx context.Context, handleUpdate func(update // Filter out nil actions actions = slices.DeleteFunc(actions, func(a *Action) bool { return a == nil }) - running := make(map[int]struct{}, len(actions)) + running := make(map[int64]struct{}, len(actions)) for _, action := range actions { if action.Status == ActionStatusRunning { running[action.ID] = struct{}{} @@ -51,18 +51,19 @@ func (c *ActionClient) WaitForFunc(ctx context.Context, handleUpdate func(update retries++ } - opts := ActionListOpts{ - Sort: []string{"status", "id"}, - ID: make([]int, 0, len(running)), - } - for actionID := range running { - opts.ID = append(opts.ID, actionID) - } - slices.Sort(opts.ID) + updates := make([]*Action, 0, len(running)) + for runningIDsChunk := range slices.Chunk(slices.Sorted(maps.Keys(running)), 25) { + opts := ActionListOpts{ + Sort: []string{"status", "id"}, + ID: runningIDsChunk, + } + + updatesChunk, err := c.AllWithOpts(ctx, opts) + if err != nil { + return err + } - updates, err := c.AllWithOpts(ctx, opts) - if err != nil { - return err + updates = append(updates, updatesChunk...) } if len(updates) != len(running) { @@ -73,7 +74,7 @@ func (c *ActionClient) WaitForFunc(ctx context.Context, handleUpdate func(update for _, update := range updates { delete(notFound, update.ID) } - notFoundIDs := make([]int, 0, len(notFound)) + notFoundIDs := make([]int64, 0, len(notFound)) for unknownID := range notFound { notFoundIDs = append(notFoundIDs, unknownID) } @@ -98,7 +99,7 @@ func (c *ActionClient) WaitForFunc(ctx context.Context, handleUpdate func(update } // WaitFor waits until all actions succeed by polling the API at the interval defined by -// [WithPollBackoffFunc]. An action is considered as succeeded when its status is either +// [WithPollOpts]. An action is considered as succeeded when its status is either // [ActionStatusSuccess]. // // If a single action fails, the function will stop waiting and the error set in the diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action_watch.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action_watch.go similarity index 94% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/action_watch.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action_watch.go index 12bda18e40941..58c2eb878d584 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/action_watch.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/action_watch.go @@ -21,7 +21,7 @@ import ( // timeout, use the [context.Context]. Once the method has stopped watching, // both returned channels are closed. // -// WatchOverallProgress uses the [WithPollBackoffFunc] of the [Client] to wait +// WatchOverallProgress uses the [WithPollOpts] of the [Client] to wait // until sending the next request. // // Deprecated: WatchOverallProgress is deprecated, use [WaitForFunc] instead. @@ -34,7 +34,7 @@ func (c *ActionClient) WatchOverallProgress(ctx context.Context, actions []*Acti defer close(progressCh) previousGlobalProgress := 0 - progressByAction := make(map[int]int, len(actions)) + progressByAction := make(map[int64]int, len(actions)) err := c.WaitForFunc(ctx, func(update *Action) error { switch update.Status { case ActionStatusRunning: @@ -86,7 +86,7 @@ func (c *ActionClient) WatchOverallProgress(ctx context.Context, actions []*Acti // timeout, use the [context.Context]. Once the method has stopped watching, // both returned channels are closed. // -// WatchProgress uses the [WithPollBackoffFunc] of the [Client] to wait until +// WatchProgress uses the [WithPollOpts] of the [Client] to wait until // sending the next request. // // Deprecated: WatchProgress is deprecated, use [WaitForFunc] instead. diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/architecture.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/architecture.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/architecture.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/architecture.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/certificate.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/certificate.go similarity index 66% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/certificate.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/certificate.go index 3ee4217abf9a2..c33b30443e930 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/certificate.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/certificate.go @@ -1,16 +1,13 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // CertificateType is the type of available certificate types. @@ -50,7 +47,7 @@ const ( // CertificateUsedByRef points to a resource that uses this certificate. type CertificateUsedByRef struct { - ID int + ID int64 Type CertificateUsedByRefType } @@ -70,7 +67,7 @@ func (st *CertificateStatus) IsFailed() bool { // Certificate represents a certificate in the Hetzner Cloud. type Certificate struct { - ID int + ID int64 Name string Labels map[string]string Type CertificateType @@ -97,42 +94,33 @@ type CertificateClient struct { } // GetByID retrieves a Certificate by its ID. If the Certificate does not exist, nil is returned. -func (c *CertificateClient) GetByID(ctx context.Context, id int) (*Certificate, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/certificates/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *CertificateClient) GetByID(ctx context.Context, id int64) (*Certificate, *Response, error) { + const opPath = "/certificates/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.CertificateGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.CertificateGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return CertificateFromSchema(body.Certificate), resp, nil + return CertificateFromSchema(respBody.Certificate), resp, nil } // GetByName retrieves a Certificate by its name. If the Certificate does not exist, nil is returned. func (c *CertificateClient) GetByName(ctx context.Context, name string) (*Certificate, *Response, error) { - if name == "" { - return nil, nil, nil - } - Certificate, response, err := c.List(ctx, CertificateListOpts{Name: name}) - if len(Certificate) == 0 { - return nil, response, err - } - return Certificate[0], response, err + return firstByName(name, func() ([]*Certificate, *Response, error) { + return c.List(ctx, CertificateListOpts{Name: name}) + }) } // Get retrieves a Certificate by its ID if the input can be parsed as an integer, otherwise it // retrieves a Certificate by its name. If the Certificate does not exist, nil is returned. func (c *CertificateClient) Get(ctx context.Context, idOrName string) (*Certificate, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, id) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // CertificateListOpts specifies options for listing Certificates. @@ -158,22 +146,17 @@ func (l CertificateListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *CertificateClient) List(ctx context.Context, opts CertificateListOpts) ([]*Certificate, *Response, error) { - path := "/certificates?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/certificates?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.CertificateListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.CertificateListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - Certificates := make([]*Certificate, 0, len(body.Certificates)) - for _, s := range body.Certificates { - Certificates = append(Certificates, CertificateFromSchema(s)) + return nil, resp, err } - return Certificates, resp, nil + + return allFromSchemaFunc(respBody.Certificates, CertificateFromSchema), resp, nil } // All returns all Certificates. @@ -183,22 +166,10 @@ func (c *CertificateClient) All(ctx context.Context) ([]*Certificate, error) { // AllWithOpts returns all Certificates for the given options. func (c *CertificateClient) AllWithOpts(ctx context.Context, opts CertificateListOpts) ([]*Certificate, error) { - allCertificates := []*Certificate{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Certificate, *Response, error) { opts.Page = page - Certificates, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allCertificates = append(allCertificates, Certificates...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allCertificates, nil } // CertificateCreateOpts specifies options for creating a new Certificate. @@ -214,7 +185,7 @@ type CertificateCreateOpts struct { // Validate checks if options are valid. func (o CertificateCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } switch o.Type { case "", CertificateTypeUploaded: @@ -222,23 +193,23 @@ func (o CertificateCreateOpts) Validate() error { case CertificateTypeManaged: return o.validateManaged() default: - return fmt.Errorf("invalid type: %s", o.Type) + return invalidFieldValue(o, "Type", o.Type) } } func (o CertificateCreateOpts) validateManaged() error { if len(o.DomainNames) == 0 { - return errors.New("no domain names") + return missingField(o, "DomainNames") } return nil } func (o CertificateCreateOpts) validateUploaded() error { if o.Certificate == "" { - return errors.New("missing certificate") + return missingField(o, "Certificate") } if o.PrivateKey == "" { - return errors.New("missing private key") + return missingField(o, "PrivateKey") } return nil } @@ -249,7 +220,7 @@ func (o CertificateCreateOpts) validateUploaded() error { // CreateCertificate to create such certificates. func (c *CertificateClient) Create(ctx context.Context, opts CertificateCreateOpts) (*Certificate, *Response, error) { if !(opts.Type == "" || opts.Type == CertificateTypeUploaded) { - return nil, nil, fmt.Errorf("invalid certificate type: %s", opts.Type) + return nil, nil, invalidFieldValue(opts, "Type", opts.Type) } result, resp, err := c.CreateCertificate(ctx, opts) if err != nil { @@ -262,16 +233,20 @@ func (c *CertificateClient) Create(ctx context.Context, opts CertificateCreateOp func (c *CertificateClient) CreateCertificate( ctx context.Context, opts CertificateCreateOpts, ) (CertificateCreateResult, *Response, error) { - var ( - action *Action - reqBody schema.CertificateCreateRequest - ) + const opPath = "/certificates" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := opPath + + result := CertificateCreateResult{} if err := opts.Validate(); err != nil { - return CertificateCreateResult{}, nil, err + return result, nil, err } - reqBody.Name = opts.Name + reqBody := schema.CertificateCreateRequest{ + Name: opts.Name, + } switch opts.Type { case "", CertificateTypeUploaded: @@ -282,32 +257,24 @@ func (c *CertificateClient) CreateCertificate( reqBody.Type = string(CertificateTypeManaged) reqBody.DomainNames = opts.DomainNames default: - return CertificateCreateResult{}, nil, fmt.Errorf("invalid certificate type: %v", opts.Type) + return result, nil, invalidFieldValue(opts, "Type", opts.Type) } if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return CertificateCreateResult{}, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/certificates", bytes.NewReader(reqBodyData)) - if err != nil { - return CertificateCreateResult{}, nil, err - } - respBody := schema.CertificateCreateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.CertificateCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return CertificateCreateResult{}, resp, err + return result, resp, err } - cert := CertificateFromSchema(respBody.Certificate) + + result.Certificate = CertificateFromSchema(respBody.Certificate) if respBody.Action != nil { - action = ActionFromSchema(*respBody.Action) + result.Action = ActionFromSchema(*respBody.Action) } - return CertificateCreateResult{Certificate: cert, Action: action}, resp, nil + return result, resp, nil } // CertificateUpdateOpts specifies options for updating a Certificate. @@ -318,6 +285,11 @@ type CertificateUpdateOpts struct { // Update updates a Certificate. func (c *CertificateClient) Update(ctx context.Context, certificate *Certificate, opts CertificateUpdateOpts) (*Certificate, *Response, error) { + const opPath = "/certificates/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, certificate.ID) + reqBody := schema.CertificateUpdateRequest{} if opts.Name != "" { reqBody.Name = &opts.Name @@ -325,46 +297,36 @@ func (c *CertificateClient) Update(ctx context.Context, certificate *Certificate if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/certificates/%d", certificate.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.CertificateUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.CertificateUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return CertificateFromSchema(respBody.Certificate), resp, nil } // Delete deletes a certificate. func (c *CertificateClient) Delete(ctx context.Context, certificate *Certificate) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/certificates/%d", certificate.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/certificates/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, certificate.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // RetryIssuance retries the issuance of a failed managed certificate. func (c *CertificateClient) RetryIssuance(ctx context.Context, certificate *Certificate) (*Action, *Response, error) { - var respBody schema.CertificateIssuanceRetryResponse + const opPath = "/certificates/%d/actions/retry" + ctx = ctxutil.SetOpPath(ctx, opPath) - req, err := c.client.NewRequest(ctx, "POST", fmt.Sprintf("/certificates/%d/actions/retry", certificate.ID), nil) - if err != nil { - return nil, nil, err - } - resp, err := c.client.Do(req, &respBody) + reqPath := fmt.Sprintf(opPath, certificate.ID) + + respBody, resp, err := postRequest[schema.CertificateIssuanceRetryResponse](ctx, c.client, reqPath, nil) if err != nil { - return nil, nil, err + return nil, resp, err } - action := ActionFromSchema(respBody.Action) - return action, resp, nil + + return ActionFromSchema(respBody.Action), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/client.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client.go similarity index 65% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/client.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client.go index 5558e3c6304fa..a56defe82db65 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/client.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client.go @@ -3,13 +3,12 @@ package hcloud import ( "bytes" "context" - "encoding/json" "errors" "fmt" "io" "math" + "math/rand" "net/http" - "net/http/httputil" "net/url" "strconv" "strings" @@ -18,8 +17,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/http/httpguts" - "github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/internal/instrumentation" ) // Endpoint is the base URL of the API. @@ -43,13 +41,43 @@ func ConstantBackoff(d time.Duration) BackoffFunc { } // ExponentialBackoff returns a BackoffFunc which implements an exponential -// backoff. -// It uses the formula: +// backoff, truncated to 60 seconds. +// See [ExponentialBackoffWithOpts] for more details. +func ExponentialBackoff(multiplier float64, base time.Duration) BackoffFunc { + return ExponentialBackoffWithOpts(ExponentialBackoffOpts{ + Base: base, + Multiplier: multiplier, + Cap: time.Minute, + }) +} + +// ExponentialBackoffOpts defines the options used by [ExponentialBackoffWithOpts]. +type ExponentialBackoffOpts struct { + Base time.Duration + Multiplier float64 + Cap time.Duration + Jitter bool +} + +// ExponentialBackoffWithOpts returns a BackoffFunc which implements an exponential +// backoff, truncated to a maximum, and an optional full jitter. // -// b^retries * d -func ExponentialBackoff(b float64, d time.Duration) BackoffFunc { +// See https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ +func ExponentialBackoffWithOpts(opts ExponentialBackoffOpts) BackoffFunc { + baseSeconds := opts.Base.Seconds() + capSeconds := opts.Cap.Seconds() + return func(retries int) time.Duration { - return time.Duration(math.Pow(b, float64(retries))) * d + // Exponential backoff + backoff := baseSeconds * math.Pow(opts.Multiplier, float64(retries)) + // Cap backoff + backoff = math.Min(capSeconds, backoff) + // Add jitter + if opts.Jitter { + backoff = ((backoff - baseSeconds) * rand.Float64()) + baseSeconds // #nosec G404 + } + + return time.Duration(backoff * float64(time.Second)) } } @@ -58,14 +86,16 @@ type Client struct { endpoint string token string tokenValid bool - backoffFunc BackoffFunc + retryBackoffFunc BackoffFunc + retryMaxRetries int pollBackoffFunc BackoffFunc httpClient *http.Client applicationName string applicationVersion string userAgent string debugWriter io.Writer - instrumentationRegistry *prometheus.Registry + instrumentationRegistry prometheus.Registerer + handler handler Action ActionClient Certificate CertificateClient @@ -110,30 +140,73 @@ func WithToken(token string) ClientOption { // polling from the API. // // Deprecated: Setting the poll interval is deprecated, you can now configure -// [WithPollBackoffFunc] with a [ConstantBackoff] to get the same results. To +// [WithPollOpts] with a [ConstantBackoff] to get the same results. To // migrate your code, replace your usage like this: // // // before // hcloud.WithPollInterval(2 * time.Second) // // now -// hcloud.WithPollBackoffFunc(hcloud.ConstantBackoff(2 * time.Second)) +// hcloud.WithPollOpts(hcloud.PollOpts{ +// BackoffFunc: hcloud.ConstantBackoff(2 * time.Second), +// }) func WithPollInterval(pollInterval time.Duration) ClientOption { - return WithPollBackoffFunc(ConstantBackoff(pollInterval)) + return WithPollOpts(PollOpts{ + BackoffFunc: ConstantBackoff(pollInterval), + }) } // WithPollBackoffFunc configures a Client to use the specified backoff // function when polling from the API. +// +// Deprecated: WithPollBackoffFunc is deprecated, use [WithPollOpts] instead. func WithPollBackoffFunc(f BackoffFunc) ClientOption { + return WithPollOpts(PollOpts{ + BackoffFunc: f, + }) +} + +// PollOpts defines the options used by [WithPollOpts]. +type PollOpts struct { + BackoffFunc BackoffFunc +} + +// WithPollOpts configures a Client to use the specified options when polling from the API. +// +// If [PollOpts.BackoffFunc] is nil, the existing backoff function will be preserved. +func WithPollOpts(opts PollOpts) ClientOption { return func(client *Client) { - client.pollBackoffFunc = f + if opts.BackoffFunc != nil { + client.pollBackoffFunc = opts.BackoffFunc + } } } // WithBackoffFunc configures a Client to use the specified backoff function. // The backoff function is used for retrying HTTP requests. +// +// Deprecated: WithBackoffFunc is deprecated, use [WithRetryOpts] instead. func WithBackoffFunc(f BackoffFunc) ClientOption { return func(client *Client) { - client.backoffFunc = f + client.retryBackoffFunc = f + } +} + +// RetryOpts defines the options used by [WithRetryOpts]. +type RetryOpts struct { + BackoffFunc BackoffFunc + MaxRetries int +} + +// WithRetryOpts configures a Client to use the specified options when retrying API +// requests. +// +// If [RetryOpts.BackoffFunc] is nil, the existing backoff function will be preserved. +func WithRetryOpts(opts RetryOpts) ClientOption { + return func(client *Client) { + if opts.BackoffFunc != nil { + client.retryBackoffFunc = opts.BackoffFunc + } + client.retryMaxRetries = opts.MaxRetries } } @@ -163,7 +236,7 @@ func WithHTTPClient(httpClient *http.Client) ClientOption { } // WithInstrumentation configures a Client to collect metrics about the performed HTTP requests. -func WithInstrumentation(registry *prometheus.Registry) ClientOption { +func WithInstrumentation(registry prometheus.Registerer) ClientOption { return func(client *Client) { client.instrumentationRegistry = registry } @@ -172,10 +245,18 @@ func WithInstrumentation(registry *prometheus.Registry) ClientOption { // NewClient creates a new client. func NewClient(options ...ClientOption) *Client { client := &Client{ - endpoint: Endpoint, - tokenValid: true, - httpClient: &http.Client{}, - backoffFunc: ExponentialBackoff(2, 500*time.Millisecond), + endpoint: Endpoint, + tokenValid: true, + httpClient: &http.Client{}, + + retryBackoffFunc: ExponentialBackoffWithOpts(ExponentialBackoffOpts{ + Base: time.Second, + Multiplier: 2, + Cap: time.Minute, + Jitter: true, + }), + retryMaxRetries: 5, + pollBackoffFunc: ConstantBackoff(500 * time.Millisecond), } @@ -186,9 +267,11 @@ func NewClient(options ...ClientOption) *Client { client.buildUserAgent() if client.instrumentationRegistry != nil { i := instrumentation.New("api", client.instrumentationRegistry) - client.httpClient.Transport = i.InstrumentedRoundTripper() + client.httpClient.Transport = i.InstrumentedRoundTripper(client.httpClient.Transport) } + client.handler = assembleHandlerChain(client) + client.Action = ActionClient{action: &ResourceActionClient{client: client}} client.Datacenter = DatacenterClient{client: client} client.FloatingIP = FloatingIPClient{client: client, Action: &ResourceActionClient{client: client, resource: "floating_ips"}} @@ -236,97 +319,10 @@ func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Re } // Do performs an HTTP request against the API. -func (c *Client) Do(r *http.Request, v interface{}) (*Response, error) { - var retries int - var body []byte - var err error - if r.ContentLength > 0 { - body, err = io.ReadAll(r.Body) - if err != nil { - r.Body.Close() - return nil, err - } - r.Body.Close() - } - for { - if r.ContentLength > 0 { - r.Body = io.NopCloser(bytes.NewReader(body)) - } - - if c.debugWriter != nil { - dumpReq, err := dumpRequest(r) - if err != nil { - return nil, err - } - fmt.Fprintf(c.debugWriter, "--- Request:\n%s\n\n", dumpReq) - } - - resp, err := c.httpClient.Do(r) - if err != nil { - return nil, err - } - response := &Response{Response: resp} - body, err := io.ReadAll(resp.Body) - if err != nil { - resp.Body.Close() - return response, err - } - resp.Body.Close() - resp.Body = io.NopCloser(bytes.NewReader(body)) - - if c.debugWriter != nil { - dumpResp, err := httputil.DumpResponse(resp, true) - if err != nil { - return nil, err - } - fmt.Fprintf(c.debugWriter, "--- Response:\n%s\n\n", dumpResp) - } - - if err = response.readMeta(body); err != nil { - return response, fmt.Errorf("hcloud: error reading response meta data: %s", err) - } - - if response.StatusCode >= 400 && response.StatusCode <= 599 { - err = errorFromResponse(response, body) - if err == nil { - err = fmt.Errorf("hcloud: server responded with status code %d", resp.StatusCode) - } else if IsError(err, ErrorCodeConflict) { - c.backoff(retries) - retries++ - continue - } - return response, err - } - if v != nil { - if w, ok := v.(io.Writer); ok { - _, err = io.Copy(w, bytes.NewReader(body)) - } else { - err = json.Unmarshal(body, v) - } - } - - return response, err - } -} - -func (c *Client) backoff(retries int) { - time.Sleep(c.backoffFunc(retries)) -} - -func (c *Client) all(f func(int) (*Response, error)) error { - var ( - page = 1 - ) - for { - resp, err := f(page) - if err != nil { - return err - } - if resp.Meta.Pagination == nil || resp.Meta.Pagination.NextPage == 0 { - return nil - } - page = resp.Meta.Pagination.NextPage - } +// v can be nil, an io.Writer to write the response body to or a pointer to +// a struct to json.Unmarshal the response to. +func (c *Client) Do(req *http.Request, v any) (*Response, error) { + return c.handler.Do(req, v) } func (c *Client) buildUserAgent() { @@ -340,43 +336,6 @@ func (c *Client) buildUserAgent() { } } -func dumpRequest(r *http.Request) ([]byte, error) { - // Duplicate the request, so we can redact the auth header - rDuplicate := r.Clone(context.Background()) - rDuplicate.Header.Set("Authorization", "REDACTED") - - // To get the request body we need to read it before the request was actually sent. - // See https://github.com/golang/go/issues/29792 - dumpReq, err := httputil.DumpRequestOut(rDuplicate, true) - if err != nil { - return nil, err - } - - // Set original request body to the duplicate created by DumpRequestOut. The request body is not duplicated - // by .Clone() and instead just referenced, so it would be completely read otherwise. - r.Body = rDuplicate.Body - - return dumpReq, nil -} - -func errorFromResponse(resp *Response, body []byte) error { - if !strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { - return nil - } - - var respBody schema.ErrorResponse - if err := json.Unmarshal(body, &respBody); err != nil { - return nil - } - if respBody.Error.Code == "" && respBody.Error.Message == "" { - return nil - } - - hcErr := ErrorFromSchema(respBody.Error) - hcErr.response = resp - return hcErr -} - const ( headerCorrelationID = "X-Correlation-Id" ) @@ -385,35 +344,34 @@ const ( type Response struct { *http.Response Meta Meta + + // body holds a copy of the http.Response body that must be used within the handler + // chain. The http.Response.Body is reserved for external users. + body []byte } -func (r *Response) readMeta(body []byte) error { - if h := r.Header.Get("RateLimit-Limit"); h != "" { - r.Meta.Ratelimit.Limit, _ = strconv.Atoi(h) - } - if h := r.Header.Get("RateLimit-Remaining"); h != "" { - r.Meta.Ratelimit.Remaining, _ = strconv.Atoi(h) - } - if h := r.Header.Get("RateLimit-Reset"); h != "" { - if ts, err := strconv.ParseInt(h, 10, 64); err == nil { - r.Meta.Ratelimit.Reset = time.Unix(ts, 0) - } +// populateBody copies the original [http.Response] body into the internal [Response] body +// property, and restore the original [http.Response] body as if it was untouched. +func (r *Response) populateBody() error { + // Read full response body and save it for later use + body, err := io.ReadAll(r.Body) + r.Body.Close() + if err != nil { + return err } + r.body = body - if strings.HasPrefix(r.Header.Get("Content-Type"), "application/json") { - var s schema.MetaResponse - if err := json.Unmarshal(body, &s); err != nil { - return err - } - if s.Meta.Pagination != nil { - p := PaginationFromSchema(*s.Meta.Pagination) - r.Meta.Pagination = &p - } - } + // Restore the body as if it was untouched, as it might be read by external users + r.Body = io.NopCloser(bytes.NewReader(body)) return nil } +// hasJSONBody returns whether the response has a JSON body. +func (r *Response) hasJSONBody() bool { + return len(r.body) > 0 && strings.HasPrefix(r.Header.Get("Content-Type"), "application/json") +} + // internalCorrelationID returns the unique ID of the request as set by the API. This ID can help with support requests, // as it allows the people working on identify this request in particular. func (r *Response) internalCorrelationID() string { diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_generic.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_generic.go new file mode 100644 index 0000000000000..dea12ad635864 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_generic.go @@ -0,0 +1,101 @@ +package hcloud + +import ( + "bytes" + "context" + "encoding/json" + "io" +) + +func getRequest[Schema any](ctx context.Context, client *Client, url string) (Schema, *Response, error) { + var respBody Schema + + req, err := client.NewRequest(ctx, "GET", url, nil) + if err != nil { + return respBody, nil, err + } + + resp, err := client.Do(req, &respBody) + if err != nil { + return respBody, resp, err + } + + return respBody, resp, nil +} + +func postRequest[Schema any](ctx context.Context, client *Client, url string, reqBody any) (Schema, *Response, error) { + var respBody Schema + + var reqBodyReader io.Reader + if reqBody != nil { + reqBodyBytes, err := json.Marshal(reqBody) + if err != nil { + return respBody, nil, err + } + + reqBodyReader = bytes.NewReader(reqBodyBytes) + } + + req, err := client.NewRequest(ctx, "POST", url, reqBodyReader) + if err != nil { + return respBody, nil, err + } + + resp, err := client.Do(req, &respBody) + if err != nil { + return respBody, resp, err + } + + return respBody, resp, nil +} + +func putRequest[Schema any](ctx context.Context, client *Client, url string, reqBody any) (Schema, *Response, error) { + var respBody Schema + + var reqBodyReader io.Reader + if reqBody != nil { + reqBodyBytes, err := json.Marshal(reqBody) + if err != nil { + return respBody, nil, err + } + + reqBodyReader = bytes.NewReader(reqBodyBytes) + } + + req, err := client.NewRequest(ctx, "PUT", url, reqBodyReader) + if err != nil { + return respBody, nil, err + } + + resp, err := client.Do(req, &respBody) + if err != nil { + return respBody, resp, err + } + + return respBody, resp, nil +} + +func deleteRequest[Schema any](ctx context.Context, client *Client, url string) (Schema, *Response, error) { + var respBody Schema + + req, err := client.NewRequest(ctx, "DELETE", url, nil) + if err != nil { + return respBody, nil, err + } + + resp, err := client.Do(req, &respBody) + if err != nil { + return respBody, resp, err + } + + return respBody, resp, nil +} + +func deleteRequestNoResult(ctx context.Context, client *Client, url string) (*Response, error) { + req, err := client.NewRequest(ctx, "DELETE", url, nil) + if err != nil { + return nil, err + } + + return client.Do(req, nil) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler.go new file mode 100644 index 0000000000000..29a9376d6bf9a --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler.go @@ -0,0 +1,56 @@ +package hcloud + +import ( + "context" + "net/http" +) + +// handler is an interface representing a client request transaction. The handler are +// meant to be chained, similarly to the [http.RoundTripper] interface. +// +// The handler chain is placed between the [Client] API operations and the +// [http.Client]. +type handler interface { + Do(req *http.Request, v any) (resp *Response, err error) +} + +// assembleHandlerChain assembles the chain of handlers used to make API requests. +// +// The order of the handlers is important. +func assembleHandlerChain(client *Client) handler { + // Start down the chain: sending the http request + h := newHTTPHandler(client.httpClient) + + // Insert debug writer if enabled + if client.debugWriter != nil { + h = wrapDebugHandler(h, client.debugWriter) + } + + // Read rate limit headers + h = wrapRateLimitHandler(h) + + // Build error from response + h = wrapErrorHandler(h) + + // Retry request if condition are met + h = wrapRetryHandler(h, client.retryBackoffFunc, client.retryMaxRetries) + + // Finally parse the response body into the provided schema + h = wrapParseHandler(h) + + return h +} + +// cloneRequest clones both the request and the request body. +func cloneRequest(req *http.Request, ctx context.Context) (cloned *http.Request, err error) { //revive:disable:context-as-argument + cloned = req.Clone(ctx) + + if req.ContentLength > 0 { + cloned.Body, err = req.GetBody() + if err != nil { + return nil, err + } + } + + return cloned, nil +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_debug.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_debug.go new file mode 100644 index 0000000000000..4aa867db44ed2 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_debug.go @@ -0,0 +1,50 @@ +package hcloud + +import ( + "context" + "fmt" + "io" + "net/http" + "net/http/httputil" +) + +func wrapDebugHandler(wrapped handler, output io.Writer) handler { + return &debugHandler{wrapped, output} +} + +type debugHandler struct { + handler handler + output io.Writer +} + +func (h *debugHandler) Do(req *http.Request, v any) (resp *Response, err error) { + // Clone the request, so we can redact the auth header, read the body + // and use a new context. + cloned, err := cloneRequest(req, context.Background()) + if err != nil { + return nil, err + } + + cloned.Header.Set("Authorization", "REDACTED") + + dumpReq, err := httputil.DumpRequestOut(cloned, true) + if err != nil { + return nil, err + } + + fmt.Fprintf(h.output, "--- Request:\n%s\n\n", dumpReq) + + resp, err = h.handler.Do(req, v) + if err != nil { + return resp, err + } + + dumpResp, err := httputil.DumpResponse(resp.Response, true) + if err != nil { + return nil, err + } + + fmt.Fprintf(h.output, "--- Response:\n%s\n\n", dumpResp) + + return resp, err +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_error.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_error.go new file mode 100644 index 0000000000000..e9191464ebe0f --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_error.go @@ -0,0 +1,53 @@ +package hcloud + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" +) + +var ErrStatusCode = errors.New("server responded with status code") + +func wrapErrorHandler(wrapped handler) handler { + return &errorHandler{wrapped} +} + +type errorHandler struct { + handler handler +} + +func (h *errorHandler) Do(req *http.Request, v any) (resp *Response, err error) { + resp, err = h.handler.Do(req, v) + if err != nil { + return resp, err + } + + if resp.StatusCode >= 400 && resp.StatusCode <= 599 { + err = errorFromBody(resp) + if err == nil { + err = fmt.Errorf("hcloud: %w %d", ErrStatusCode, resp.StatusCode) + } + } + return resp, err +} + +func errorFromBody(resp *Response) error { + if !resp.hasJSONBody() { + return nil + } + + var s schema.ErrorResponse + if err := json.Unmarshal(resp.body, &s); err != nil { + return nil // nolint: nilerr + } + if s.Error.Code == "" && s.Error.Message == "" { + return nil + } + + hcErr := ErrorFromSchema(s.Error) + hcErr.response = resp + return hcErr +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_http.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_http.go new file mode 100644 index 0000000000000..c0a02fe398681 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_http.go @@ -0,0 +1,28 @@ +package hcloud + +import ( + "net/http" +) + +func newHTTPHandler(httpClient *http.Client) handler { + return &httpHandler{httpClient} +} + +type httpHandler struct { + httpClient *http.Client +} + +func (h *httpHandler) Do(req *http.Request, _ interface{}) (*Response, error) { + httpResponse, err := h.httpClient.Do(req) //nolint: bodyclose + resp := &Response{Response: httpResponse} + if err != nil { + return resp, err + } + + err = resp.populateBody() + if err != nil { + return resp, err + } + + return resp, err +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_parse.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_parse.go new file mode 100644 index 0000000000000..7f42b16a378f5 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_parse.go @@ -0,0 +1,50 @@ +package hcloud + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" +) + +func wrapParseHandler(wrapped handler) handler { + return &parseHandler{wrapped} +} + +type parseHandler struct { + handler handler +} + +func (h *parseHandler) Do(req *http.Request, v any) (resp *Response, err error) { + // respBody is not needed down the handler chain + resp, err = h.handler.Do(req, nil) + if err != nil { + return resp, err + } + + if resp.hasJSONBody() { + // Parse the response meta + var s schema.MetaResponse + if err := json.Unmarshal(resp.body, &s); err != nil { + return resp, fmt.Errorf("hcloud: error reading response meta data: %w", err) + } + if s.Meta.Pagination != nil { + p := PaginationFromSchema(*s.Meta.Pagination) + resp.Meta.Pagination = &p + } + } + + // Parse the response schema + if v != nil { + if w, ok := v.(io.Writer); ok { + _, err = io.Copy(w, bytes.NewReader(resp.body)) + } else { + err = json.Unmarshal(resp.body, v) + } + } + + return resp, err +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_rate_limit.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_rate_limit.go new file mode 100644 index 0000000000000..4c53ba9e9a13f --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_rate_limit.go @@ -0,0 +1,36 @@ +package hcloud + +import ( + "net/http" + "strconv" + "time" +) + +func wrapRateLimitHandler(wrapped handler) handler { + return &rateLimitHandler{wrapped} +} + +type rateLimitHandler struct { + handler handler +} + +func (h *rateLimitHandler) Do(req *http.Request, v any) (resp *Response, err error) { + resp, err = h.handler.Do(req, v) + + // Ensure the embedded [*http.Response] is not nil, e.g. on canceled context + if resp != nil && resp.Response != nil && resp.Response.Header != nil { + if h := resp.Header.Get("RateLimit-Limit"); h != "" { + resp.Meta.Ratelimit.Limit, _ = strconv.Atoi(h) + } + if h := resp.Header.Get("RateLimit-Remaining"); h != "" { + resp.Meta.Ratelimit.Remaining, _ = strconv.Atoi(h) + } + if h := resp.Header.Get("RateLimit-Reset"); h != "" { + if ts, err := strconv.ParseInt(h, 10, 64); err == nil { + resp.Meta.Ratelimit.Reset = time.Unix(ts, 0) + } + } + } + + return resp, err +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_retry.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_retry.go new file mode 100644 index 0000000000000..b0983c9699486 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_handler_retry.go @@ -0,0 +1,84 @@ +package hcloud + +import ( + "errors" + "net" + "net/http" + "time" +) + +func wrapRetryHandler(wrapped handler, backoffFunc BackoffFunc, maxRetries int) handler { + return &retryHandler{wrapped, backoffFunc, maxRetries} +} + +type retryHandler struct { + handler handler + backoffFunc BackoffFunc + maxRetries int +} + +func (h *retryHandler) Do(req *http.Request, v any) (resp *Response, err error) { + retries := 0 + ctx := req.Context() + + for { + // Clone the request using the original context + cloned, err := cloneRequest(req, ctx) + if err != nil { + return nil, err + } + + resp, err = h.handler.Do(cloned, v) + if err != nil { + // Beware the diversity of the errors: + // - request preparation + // - network connectivity + // - http status code (see [errorHandler]) + if ctx.Err() != nil { + // early return if the context was canceled or timed out + return resp, err + } + + if retries < h.maxRetries && retryPolicy(resp, err) { + select { + case <-ctx.Done(): + return resp, err + case <-time.After(h.backoffFunc(retries)): + retries++ + continue + } + } + } + + return resp, err + } +} + +func retryPolicy(resp *Response, err error) bool { + if err != nil { + var apiErr Error + var netErr net.Error + + switch { + case errors.As(err, &apiErr): + switch apiErr.Code { //nolint:exhaustive + case ErrorCodeConflict: + return true + case ErrorCodeRateLimitExceeded: + return true + } + case errors.Is(err, ErrStatusCode): + switch resp.Response.StatusCode { + // 5xx errors + case http.StatusBadGateway, http.StatusGatewayTimeout: + return true + } + case errors.As(err, &netErr): + if netErr.Timeout() { + return true + } + } + } + + return false +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_helper.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_helper.go new file mode 100644 index 0000000000000..819ae2460ebd8 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/client_helper.go @@ -0,0 +1,85 @@ +package hcloud + +import ( + "context" + "strconv" +) + +// allFromSchemaFunc transform each item in the list using the FromSchema function, and +// returns the result. +func allFromSchemaFunc[T, V any](all []T, fn func(T) V) []V { + result := make([]V, len(all)) + for i, t := range all { + result[i] = fn(t) + } + + return result +} + +// iterPages fetches each pages using the list function, and returns the result. +func iterPages[T any](listFn func(int) ([]*T, *Response, error)) ([]*T, error) { + page := 1 + result := []*T{} + + for { + pageResult, resp, err := listFn(page) + if err != nil { + return nil, err + } + + result = append(result, pageResult...) + + if resp.Meta.Pagination == nil || resp.Meta.Pagination.NextPage == 0 { + return result, nil + } + page = resp.Meta.Pagination.NextPage + } +} + +// firstBy fetches a list of items using the list function, and returns the first item +// of the list if present otherwise nil. +func firstBy[T any](listFn func() ([]*T, *Response, error)) (*T, *Response, error) { + items, resp, err := listFn() + if len(items) == 0 { + return nil, resp, err + } + + return items[0], resp, err +} + +// firstByName is a wrapper around [firstBy], that checks if the provided name is not +// empty. +func firstByName[T any](name string, listFn func() ([]*T, *Response, error)) (*T, *Response, error) { + if name == "" { + return nil, nil, nil + } + + return firstBy(listFn) +} + +// getByIDOrName fetches the resource by ID when the identifier is an integer, otherwise +// by Name. To support resources that have a integer as Name, an additional attempt is +// made to fetch the resource by Name using the ID. +// +// Since API managed resources (locations, server types, ...) do not have integers as +// names, this function is only meaningful for user managed resources (ssh keys, +// servers). +func getByIDOrName[T any]( + ctx context.Context, + getByIDFn func(ctx context.Context, id int64) (*T, *Response, error), + getByNameFn func(ctx context.Context, name string) (*T, *Response, error), + idOrName string, +) (*T, *Response, error) { + if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { + result, resp, err := getByIDFn(ctx, id) + if err != nil { + return result, resp, err + } + if result != nil { + return result, resp, err + } + // Fallback to get by Name if the resource was not found + } + + return getByNameFn(ctx, idOrName) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/datacenter.go similarity index 60% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/datacenter.go index 4c30de3b9d7f9..70d61bbed8676 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/datacenter.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/datacenter.go @@ -6,12 +6,13 @@ import ( "net/url" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Datacenter represents a datacenter in the Hetzner Cloud. type Datacenter struct { - ID int + ID int64 Name string Description string Location *Location @@ -20,8 +21,9 @@ type Datacenter struct { // DatacenterServerTypes represents the server types available and supported in a datacenter. type DatacenterServerTypes struct { - Supported []*ServerType - Available []*ServerType + Supported []*ServerType + AvailableForMigration []*ServerType + Available []*ServerType } // DatacenterClient is a client for the datacenter API. @@ -30,40 +32,35 @@ type DatacenterClient struct { } // GetByID retrieves a datacenter by its ID. If the datacenter does not exist, nil is returned. -func (c *DatacenterClient) GetByID(ctx context.Context, id int) (*Datacenter, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/datacenters/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *DatacenterClient) GetByID(ctx context.Context, id int64) (*Datacenter, *Response, error) { + const opPath = "/datacenters/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.DatacenterGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.DatacenterGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } return nil, resp, err } - return DatacenterFromSchema(body.Datacenter), resp, nil + + return DatacenterFromSchema(respBody.Datacenter), resp, nil } // GetByName retrieves a datacenter by its name. If the datacenter does not exist, nil is returned. func (c *DatacenterClient) GetByName(ctx context.Context, name string) (*Datacenter, *Response, error) { - if name == "" { - return nil, nil, nil - } - datacenters, response, err := c.List(ctx, DatacenterListOpts{Name: name}) - if len(datacenters) == 0 { - return nil, response, err - } - return datacenters[0], response, err + return firstByName(name, func() ([]*Datacenter, *Response, error) { + return c.List(ctx, DatacenterListOpts{Name: name}) + }) } // Get retrieves a datacenter by its ID if the input can be parsed as an integer, otherwise it // retrieves a datacenter by its name. If the datacenter does not exist, nil is returned. func (c *DatacenterClient) Get(ctx context.Context, idOrName string) (*Datacenter, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) + if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { + return c.GetByID(ctx, id) } return c.GetByName(ctx, idOrName) } @@ -91,22 +88,17 @@ func (l DatacenterListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *DatacenterClient) List(ctx context.Context, opts DatacenterListOpts) ([]*Datacenter, *Response, error) { - path := "/datacenters?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/datacenters?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.DatacenterListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.DatacenterListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - datacenters := make([]*Datacenter, 0, len(body.Datacenters)) - for _, i := range body.Datacenters { - datacenters = append(datacenters, DatacenterFromSchema(i)) + return nil, resp, err } - return datacenters, resp, nil + + return allFromSchemaFunc(respBody.Datacenters, DatacenterFromSchema), resp, nil } // All returns all datacenters. @@ -116,20 +108,8 @@ func (c *DatacenterClient) All(ctx context.Context) ([]*Datacenter, error) { // AllWithOpts returns all datacenters for the given options. func (c *DatacenterClient) AllWithOpts(ctx context.Context, opts DatacenterListOpts) ([]*Datacenter, error) { - allDatacenters := []*Datacenter{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Datacenter, *Response, error) { opts.Page = page - datacenters, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allDatacenters = append(allDatacenters, datacenters...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allDatacenters, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/deprecation.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/deprecation.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/deprecation.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/deprecation.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/error.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/error.go similarity index 82% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/error.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/error.go index 371a92e31edbe..0e6f556b9bb9f 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/error.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/error.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "net" + "slices" + "strings" ) // ErrorCode represents an error code returned from the API. @@ -29,6 +31,7 @@ const ( ErrorCodeRobotUnavailable ErrorCode = "robot_unavailable" // Robot was not available. The caller may retry the operation after a short delay ErrorCodeResourceLocked ErrorCode = "resource_locked" // The resource is locked. The caller should contact support ErrorUnsupportedError ErrorCode = "unsupported_error" // The given resource does not support this + ErrorDeprecatedAPIEndpoint ErrorCode = "deprecated_api_endpoint" // The request can not be answered because the API functionality was removed // Server related error codes. @@ -126,11 +129,16 @@ type ErrorDetailsInvalidInputField struct { Messages []string } -// IsError returns whether err is an API error with the given error code. -func IsError(err error, code ErrorCode) bool { +// ErrorDetailsDeprecatedAPIEndpoint contains the details of a 'deprecated_api_endpoint' error. +type ErrorDetailsDeprecatedAPIEndpoint struct { + Announcement string +} + +// IsError returns whether err is an API error with one of the given error codes. +func IsError(err error, code ...ErrorCode) bool { var apiErr Error ok := errors.As(err, &apiErr) - return ok && apiErr.Code == code + return ok && slices.Index(code, apiErr.Code) > -1 } type InvalidIPError struct { @@ -148,3 +156,40 @@ type DNSNotFoundError struct { func (e DNSNotFoundError) Error() string { return fmt.Sprintf("dns for ip %s not found", e.IP.String()) } + +// ArgumentError is a type of error returned when validating arguments. +type ArgumentError string + +func (e ArgumentError) Error() string { return string(e) } + +func newArgumentErrorf(format string, args ...any) ArgumentError { + return ArgumentError(fmt.Sprintf(format, args...)) +} + +func missingArgument(name string, obj any) error { + return newArgumentErrorf("missing argument '%s' [%T]", name, obj) +} + +func invalidArgument(name string, obj any) error { + return newArgumentErrorf("invalid value '%v' for argument '%s' [%T]", obj, name, obj) +} + +func missingField(obj any, field string) error { + return newArgumentErrorf("missing field [%s] in [%T]", field, obj) +} + +func invalidFieldValue(obj any, field string, value any) error { + return newArgumentErrorf("invalid value '%v' for field [%s] in [%T]", value, field, obj) +} + +func missingOneOfFields(obj any, fields ...string) error { + return newArgumentErrorf("missing one of fields [%s] in [%T]", strings.Join(fields, ", "), obj) +} + +func mutuallyExclusiveFields(obj any, fields ...string) error { + return newArgumentErrorf("found mutually exclusive fields [%s] in [%T]", strings.Join(fields, ", "), obj) +} + +func missingRequiredTogetherFields(obj any, fields ...string) error { + return newArgumentErrorf("missing required together fields [%s] in [%T]", strings.Join(fields, ", "), obj) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil/ctxutil.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil/ctxutil.go new file mode 100644 index 0000000000000..de0ce95f5cce0 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil/ctxutil.go @@ -0,0 +1,30 @@ +package ctxutil + +import ( + "context" + "strings" +) + +// key is an unexported type to prevents collisions with keys defined in other packages. +type key struct{} + +// opPathKey is the key for operation path in Contexts. +var opPathKey = key{} + +// SetOpPath processes the operation path and save it in the context before returning it. +func SetOpPath(ctx context.Context, path string) context.Context { + path, _, _ = strings.Cut(path, "?") + path = strings.ReplaceAll(path, "%d", "-") + path = strings.ReplaceAll(path, "%s", "-") + + return context.WithValue(ctx, opPathKey, path) +} + +// OpPath returns the operation path from the context. +func OpPath(ctx context.Context) string { + result, ok := ctx.Value(opPathKey).(string) + if !ok { + return "" + } + return result +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/firewall.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/firewall.go similarity index 64% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/firewall.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/firewall.go index 29c52327c04b7..abfe438521fa0 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/firewall.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/firewall.go @@ -1,22 +1,19 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Firewall represents a Firewall in the Hetzner Cloud. type Firewall struct { - ID int + ID int64 Name string Labels map[string]string Created time.Time @@ -80,7 +77,7 @@ type FirewallResource struct { // FirewallResourceServer represents a Server to apply a Firewall on. type FirewallResourceServer struct { - ID int + ID int64 } // FirewallResourceLabelSelector represents a LabelSelector to apply a Firewall on. @@ -95,42 +92,34 @@ type FirewallClient struct { } // GetByID retrieves a Firewall by its ID. If the Firewall does not exist, nil is returned. -func (c *FirewallClient) GetByID(ctx context.Context, id int) (*Firewall, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/firewalls/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *FirewallClient) GetByID(ctx context.Context, id int64) (*Firewall, *Response, error) { + const opPath = "/firewalls/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.FirewallGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.FirewallGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return FirewallFromSchema(body.Firewall), resp, nil + + return FirewallFromSchema(respBody.Firewall), resp, nil } // GetByName retrieves a Firewall by its name. If the Firewall does not exist, nil is returned. func (c *FirewallClient) GetByName(ctx context.Context, name string) (*Firewall, *Response, error) { - if name == "" { - return nil, nil, nil - } - firewalls, response, err := c.List(ctx, FirewallListOpts{Name: name}) - if len(firewalls) == 0 { - return nil, response, err - } - return firewalls[0], response, err + return firstByName(name, func() ([]*Firewall, *Response, error) { + return c.List(ctx, FirewallListOpts{Name: name}) + }) } // Get retrieves a Firewall by its ID if the input can be parsed as an integer, otherwise it // retrieves a Firewall by its name. If the Firewall does not exist, nil is returned. func (c *FirewallClient) Get(ctx context.Context, idOrName string) (*Firewall, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, id) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // FirewallListOpts specifies options for listing Firewalls. @@ -156,22 +145,17 @@ func (l FirewallListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *FirewallClient) List(ctx context.Context, opts FirewallListOpts) ([]*Firewall, *Response, error) { - path := "/firewalls?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/firewalls?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.FirewallListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.FirewallListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - firewalls := make([]*Firewall, 0, len(body.Firewalls)) - for _, s := range body.Firewalls { - firewalls = append(firewalls, FirewallFromSchema(s)) + return nil, resp, err } - return firewalls, resp, nil + + return allFromSchemaFunc(respBody.Firewalls, FirewallFromSchema), resp, nil } // All returns all Firewalls. @@ -181,22 +165,10 @@ func (c *FirewallClient) All(ctx context.Context) ([]*Firewall, error) { // AllWithOpts returns all Firewalls for the given options. func (c *FirewallClient) AllWithOpts(ctx context.Context, opts FirewallListOpts) ([]*Firewall, error) { - allFirewalls := []*Firewall{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Firewall, *Response, error) { opts.Page = page - firewalls, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allFirewalls = append(allFirewalls, firewalls...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allFirewalls, nil } // FirewallCreateOpts specifies options for creating a new Firewall. @@ -210,7 +182,7 @@ type FirewallCreateOpts struct { // Validate checks if options are valid. func (o FirewallCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } return nil } @@ -223,28 +195,27 @@ type FirewallCreateResult struct { // Create creates a new Firewall. func (c *FirewallClient) Create(ctx context.Context, opts FirewallCreateOpts) (FirewallCreateResult, *Response, error) { + const opPath = "/firewalls" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := FirewallCreateResult{} + + reqPath := opPath + if err := opts.Validate(); err != nil { - return FirewallCreateResult{}, nil, err + return result, nil, err } + reqBody := firewallCreateOptsToSchema(opts) - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return FirewallCreateResult{}, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/firewalls", bytes.NewReader(reqBodyData)) - if err != nil { - return FirewallCreateResult{}, nil, err - } - respBody := schema.FirewallCreateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FirewallCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return FirewallCreateResult{}, resp, err - } - result := FirewallCreateResult{ - Firewall: FirewallFromSchema(respBody.Firewall), - Actions: ActionsFromSchema(respBody.Actions), + return result, resp, err } + + result.Firewall = FirewallFromSchema(respBody.Firewall) + result.Actions = ActionsFromSchema(respBody.Actions) + return result, resp, nil } @@ -256,6 +227,11 @@ type FirewallUpdateOpts struct { // Update updates a Firewall. func (c *FirewallClient) Update(ctx context.Context, firewall *Firewall, opts FirewallUpdateOpts) (*Firewall, *Response, error) { + const opPath = "/firewalls/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, firewall.ID) + reqBody := schema.FirewallUpdateRequest{} if opts.Name != "" { reqBody.Name = &opts.Name @@ -263,32 +239,23 @@ func (c *FirewallClient) Update(ctx context.Context, firewall *Firewall, opts Fi if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/firewalls/%d", firewall.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.FirewallUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.FirewallUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return FirewallFromSchema(respBody.Firewall), resp, nil } // Delete deletes a Firewall. func (c *FirewallClient) Delete(ctx context.Context, firewall *Firewall) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/firewalls/%d", firewall.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/firewalls/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, firewall.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // FirewallSetRulesOpts specifies options for setting rules of a Firewall. @@ -298,75 +265,59 @@ type FirewallSetRulesOpts struct { // SetRules sets the rules of a Firewall. func (c *FirewallClient) SetRules(ctx context.Context, firewall *Firewall, opts FirewallSetRulesOpts) ([]*Action, *Response, error) { - reqBody := firewallSetRulesOptsToSchema(opts) + const opPath = "/firewalls/%d/actions/set_rules" + ctx = ctxutil.SetOpPath(ctx, opPath) - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + reqPath := fmt.Sprintf(opPath, firewall.ID) - path := fmt.Sprintf("/firewalls/%d/actions/set_rules", firewall.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + reqBody := firewallSetRulesOptsToSchema(opts) - var respBody schema.FirewallActionSetRulesResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FirewallActionSetRulesResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionsFromSchema(respBody.Actions), resp, nil } func (c *FirewallClient) ApplyResources(ctx context.Context, firewall *Firewall, resources []FirewallResource) ([]*Action, *Response, error) { + const opPath = "/firewalls/%d/actions/apply_to_resources" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, firewall.ID) + applyTo := make([]schema.FirewallResource, len(resources)) for i, r := range resources { applyTo[i] = firewallResourceToSchema(r) } reqBody := schema.FirewallActionApplyToResourcesRequest{ApplyTo: applyTo} - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/firewalls/%d/actions/apply_to_resources", firewall.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.FirewallActionApplyToResourcesResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FirewallActionApplyToResourcesResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionsFromSchema(respBody.Actions), resp, nil } func (c *FirewallClient) RemoveResources(ctx context.Context, firewall *Firewall, resources []FirewallResource) ([]*Action, *Response, error) { + const opPath = "/firewalls/%d/actions/remove_from_resources" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, firewall.ID) + removeFrom := make([]schema.FirewallResource, len(resources)) for i, r := range resources { removeFrom[i] = firewallResourceToSchema(r) } reqBody := schema.FirewallActionRemoveFromResourcesRequest{RemoveFrom: removeFrom} - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/firewalls/%d/actions/remove_from_resources", firewall.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.FirewallActionRemoveFromResourcesResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FirewallActionRemoveFromResourcesResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionsFromSchema(respBody.Actions), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/floating_ip.go similarity index 62% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/floating_ip.go index 085b27eaeb383..bf190c4bc5cef 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/floating_ip.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/floating_ip.go @@ -1,22 +1,19 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // FloatingIP represents a Floating IP in the Hetzner Cloud. type FloatingIP struct { - ID int + ID int64 Description string Created time.Time IP net.IP @@ -54,26 +51,21 @@ const ( // changeDNSPtr changes or resets the reverse DNS pointer for an IP address. // Pass a nil ptr to reset the reverse DNS pointer to its default value. func (f *FloatingIP) changeDNSPtr(ctx context.Context, client *Client, ip net.IP, ptr *string) (*Action, *Response, error) { + const opPath = "/floating_ips/%d/actions/change_dns_ptr" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, f.ID) + reqBody := schema.FloatingIPActionChangeDNSPtrRequest{ IP: ip.String(), DNSPtr: ptr, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/floating_ips/%d/actions/change_dns_ptr", f.ID) - req, err := client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.FloatingIPActionChangeDNSPtrResponse{} - resp, err := client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FloatingIPActionChangeDNSPtrResponse](ctx, client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -96,42 +88,34 @@ type FloatingIPClient struct { // GetByID retrieves a Floating IP by its ID. If the Floating IP does not exist, // nil is returned. -func (c *FloatingIPClient) GetByID(ctx context.Context, id int) (*FloatingIP, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/floating_ips/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *FloatingIPClient) GetByID(ctx context.Context, id int64) (*FloatingIP, *Response, error) { + const opPath = "/floating_ips/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.FloatingIPGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.FloatingIPGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } return nil, resp, err } - return FloatingIPFromSchema(body.FloatingIP), resp, nil + + return FloatingIPFromSchema(respBody.FloatingIP), resp, nil } // GetByName retrieves a Floating IP by its name. If the Floating IP does not exist, nil is returned. func (c *FloatingIPClient) GetByName(ctx context.Context, name string) (*FloatingIP, *Response, error) { - if name == "" { - return nil, nil, nil - } - floatingIPs, response, err := c.List(ctx, FloatingIPListOpts{Name: name}) - if len(floatingIPs) == 0 { - return nil, response, err - } - return floatingIPs[0], response, err + return firstByName(name, func() ([]*FloatingIP, *Response, error) { + return c.List(ctx, FloatingIPListOpts{Name: name}) + }) } // Get retrieves a Floating IP by its ID if the input can be parsed as an integer, otherwise it // retrieves a Floating IP by its name. If the Floating IP does not exist, nil is returned. func (c *FloatingIPClient) Get(ctx context.Context, idOrName string) (*FloatingIP, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, id) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // FloatingIPListOpts specifies options for listing Floating IPs. @@ -157,22 +141,17 @@ func (l FloatingIPListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *FloatingIPClient) List(ctx context.Context, opts FloatingIPListOpts) ([]*FloatingIP, *Response, error) { - path := "/floating_ips?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/floating_ips?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.FloatingIPListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.FloatingIPListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - floatingIPs := make([]*FloatingIP, 0, len(body.FloatingIPs)) - for _, s := range body.FloatingIPs { - floatingIPs = append(floatingIPs, FloatingIPFromSchema(s)) + return nil, resp, err } - return floatingIPs, resp, nil + + return allFromSchemaFunc(respBody.FloatingIPs, FloatingIPFromSchema), resp, nil } // All returns all Floating IPs. @@ -182,22 +161,10 @@ func (c *FloatingIPClient) All(ctx context.Context) ([]*FloatingIP, error) { // AllWithOpts returns all Floating IPs for the given options. func (c *FloatingIPClient) AllWithOpts(ctx context.Context, opts FloatingIPListOpts) ([]*FloatingIP, error) { - allFloatingIPs := []*FloatingIP{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*FloatingIP, *Response, error) { opts.Page = page - floatingIPs, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allFloatingIPs = append(allFloatingIPs, floatingIPs...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allFloatingIPs, nil } // FloatingIPCreateOpts specifies options for creating a Floating IP. @@ -216,10 +183,10 @@ func (o FloatingIPCreateOpts) Validate() error { case FloatingIPTypeIPv4, FloatingIPTypeIPv6: break default: - return errors.New("missing or invalid type") + return invalidFieldValue(o, "Type", o.Type) } if o.HomeLocation == nil && o.Server == nil { - return errors.New("one of home location or server is required") + return missingOneOfFields(o, "HomeLocation", "Server") } return nil } @@ -232,8 +199,15 @@ type FloatingIPCreateResult struct { // Create creates a Floating IP. func (c *FloatingIPClient) Create(ctx context.Context, opts FloatingIPCreateOpts) (FloatingIPCreateResult, *Response, error) { + result := FloatingIPCreateResult{} + + const opPath = "/floating_ips" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := opPath + if err := opts.Validate(); err != nil { - return FloatingIPCreateResult{}, nil, err + return result, nil, err } reqBody := schema.FloatingIPCreateRequest{ @@ -250,38 +224,28 @@ func (c *FloatingIPClient) Create(ctx context.Context, opts FloatingIPCreateOpts if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return FloatingIPCreateResult{}, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/floating_ips", bytes.NewReader(reqBodyData)) + respBody, resp, err := postRequest[schema.FloatingIPCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return FloatingIPCreateResult{}, nil, err + return result, resp, err } - var respBody schema.FloatingIPCreateResponse - resp, err := c.client.Do(req, &respBody) - if err != nil { - return FloatingIPCreateResult{}, resp, err - } - var action *Action + result.FloatingIP = FloatingIPFromSchema(respBody.FloatingIP) if respBody.Action != nil { - action = ActionFromSchema(*respBody.Action) + result.Action = ActionFromSchema(*respBody.Action) } - return FloatingIPCreateResult{ - FloatingIP: FloatingIPFromSchema(respBody.FloatingIP), - Action: action, - }, resp, nil + + return result, resp, nil } // Delete deletes a Floating IP. func (c *FloatingIPClient) Delete(ctx context.Context, floatingIP *FloatingIP) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/floating_ips/%d", floatingIP.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/floating_ips/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, floatingIP.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // FloatingIPUpdateOpts specifies options for updating a Floating IP. @@ -293,6 +257,11 @@ type FloatingIPUpdateOpts struct { // Update updates a Floating IP. func (c *FloatingIPClient) Update(ctx context.Context, floatingIP *FloatingIP, opts FloatingIPUpdateOpts) (*FloatingIP, *Response, error) { + const opPath = "/floating_ips/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, floatingIP.ID) + reqBody := schema.FloatingIPUpdateRequest{ Description: opts.Description, Name: opts.Name, @@ -300,68 +269,48 @@ func (c *FloatingIPClient) Update(ctx context.Context, floatingIP *FloatingIP, o if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/floating_ips/%d", floatingIP.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.FloatingIPUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.FloatingIPUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return FloatingIPFromSchema(respBody.FloatingIP), resp, nil } // Assign assigns a Floating IP to a server. func (c *FloatingIPClient) Assign(ctx context.Context, floatingIP *FloatingIP, server *Server) (*Action, *Response, error) { + const opPath = "/floating_ips/%d/actions/assign" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, floatingIP.ID) + reqBody := schema.FloatingIPActionAssignRequest{ Server: server.ID, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/floating_ips/%d/actions/assign", floatingIP.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.FloatingIPActionAssignResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FloatingIPActionAssignResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // Unassign unassigns a Floating IP from the currently assigned server. func (c *FloatingIPClient) Unassign(ctx context.Context, floatingIP *FloatingIP) (*Action, *Response, error) { - var reqBody schema.FloatingIPActionUnassignRequest - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/floating_ips/%d/actions/unassign" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/floating_ips/%d/actions/unassign", floatingIP.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + reqPath := fmt.Sprintf(opPath, floatingIP.ID) + + reqBody := schema.FloatingIPActionUnassignRequest{} - var respBody schema.FloatingIPActionUnassignResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FloatingIPActionUnassignResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -382,24 +331,19 @@ type FloatingIPChangeProtectionOpts struct { // ChangeProtection changes the resource protection level of a Floating IP. func (c *FloatingIPClient) ChangeProtection(ctx context.Context, floatingIP *FloatingIP, opts FloatingIPChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/floating_ips/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, floatingIP.ID) + reqBody := schema.FloatingIPActionChangeProtectionRequest{ Delete: opts.Delete, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/floating_ips/%d/actions/change_protection", floatingIP.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.FloatingIPActionChangeProtectionResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.FloatingIPActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/hcloud.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/hcloud.go new file mode 100644 index 0000000000000..6b1d6fde01567 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/hcloud.go @@ -0,0 +1,34 @@ +/* +Package hcloud is a library for the Hetzner Cloud API. + +The Hetzner Cloud API reference is available at https://docs.hetzner.cloud. + +Make sure to follow our API changelog available at https://docs.hetzner.cloud/changelog +(or the RRS feed available at https://docs.hetzner.cloud/changelog/feed.rss) to be +notified about additions, deprecations and removals. + +# Retry mechanism + +The [Client.Do] method will retry failed requests that match certain criteria. The +default retry interval is defined by an exponential backoff algorithm truncated to 60s +with jitter. The default maximal number of retries is 5. + +The following rules defines when a request can be retried: + +When the [http.Client] returned a network timeout error. + +When the API returned an HTTP error, with the status code: + - [http.StatusBadGateway] + - [http.StatusGatewayTimeout] + +When the API returned an application error, with the code: + - [ErrorCodeConflict] + - [ErrorCodeRateLimitExceeded] + +Changes to the retry policy might occur between releases, and will not be considered +breaking changes. +*/ +package hcloud + +// Version is the library's version following Semantic Versioning. +const Version = "2.21.1" // x-releaser-pleaser-version diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/helper.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/helper.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/helper.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/helper.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/image.go similarity index 68% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/image.go index 82ff8f0a07cfe..a7d3f9a0c355f 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/image.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/image.go @@ -1,20 +1,19 @@ package hcloud import ( - "bytes" "context" - "encoding/json" "fmt" "net/url" "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Image represents an Image in the Hetzner Cloud. type Image struct { - ID int + ID int64 Name string Type ImageType Status ImageStatus @@ -82,35 +81,30 @@ type ImageClient struct { } // GetByID retrieves an image by its ID. If the image does not exist, nil is returned. -func (c *ImageClient) GetByID(ctx context.Context, id int) (*Image, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/images/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *ImageClient) GetByID(ctx context.Context, id int64) (*Image, *Response, error) { + const opPath = "/images/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.ImageGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ImageGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return ImageFromSchema(body.Image), resp, nil + + return ImageFromSchema(respBody.Image), resp, nil } // GetByName retrieves an image by its name. If the image does not exist, nil is returned. // // Deprecated: Use [ImageClient.GetByNameAndArchitecture] instead. func (c *ImageClient) GetByName(ctx context.Context, name string) (*Image, *Response, error) { - if name == "" { - return nil, nil, nil - } - images, response, err := c.List(ctx, ImageListOpts{Name: name}) - if len(images) == 0 { - return nil, response, err - } - return images[0], response, err + return firstByName(name, func() ([]*Image, *Response, error) { + return c.List(ctx, ImageListOpts{Name: name}) + }) } // GetByNameAndArchitecture retrieves an image by its name and architecture. If the image does not exist, @@ -118,14 +112,9 @@ func (c *ImageClient) GetByName(ctx context.Context, name string) (*Image, *Resp // In contrast to [ImageClient.Get], this method also returns deprecated images. Depending on your needs you should // check for this in your calling method. func (c *ImageClient) GetByNameAndArchitecture(ctx context.Context, name string, architecture Architecture) (*Image, *Response, error) { - if name == "" { - return nil, nil, nil - } - images, response, err := c.List(ctx, ImageListOpts{Name: name, Architecture: []Architecture{architecture}, IncludeDeprecated: true}) - if len(images) == 0 { - return nil, response, err - } - return images[0], response, err + return firstByName(name, func() ([]*Image, *Response, error) { + return c.List(ctx, ImageListOpts{Name: name, Architecture: []Architecture{architecture}, IncludeDeprecated: true}) + }) } // Get retrieves an image by its ID if the input can be parsed as an integer, otherwise it @@ -133,10 +122,7 @@ func (c *ImageClient) GetByNameAndArchitecture(ctx context.Context, name string, // // Deprecated: Use [ImageClient.GetForArchitecture] instead. func (c *ImageClient) Get(ctx context.Context, idOrName string) (*Image, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, id) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // GetForArchitecture retrieves an image by its ID if the input can be parsed as an integer, otherwise it @@ -145,10 +131,13 @@ func (c *ImageClient) Get(ctx context.Context, idOrName string) (*Image, *Respon // In contrast to [ImageClient.Get], this method also returns deprecated images. Depending on your needs you should // check for this in your calling method. func (c *ImageClient) GetForArchitecture(ctx context.Context, idOrName string, architecture Architecture) (*Image, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, id) - } - return c.GetByNameAndArchitecture(ctx, idOrName, architecture) + return getByIDOrName(ctx, + c.GetByID, + func(ctx context.Context, name string) (*Image, *Response, error) { + return c.GetByNameAndArchitecture(ctx, name, architecture) + }, + idOrName, + ) } // ImageListOpts specifies options for listing images. @@ -169,7 +158,7 @@ func (l ImageListOpts) values() url.Values { vals.Add("type", string(typ)) } if l.BoundTo != nil { - vals.Add("bound_to", strconv.Itoa(l.BoundTo.ID)) + vals.Add("bound_to", strconv.FormatInt(l.BoundTo.ID, 10)) } if l.Name != "" { vals.Add("name", l.Name) @@ -194,22 +183,17 @@ func (l ImageListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *ImageClient) List(ctx context.Context, opts ImageListOpts) ([]*Image, *Response, error) { - path := "/images?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/images?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.ImageListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ImageListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - images := make([]*Image, 0, len(body.Images)) - for _, i := range body.Images { - images = append(images, ImageFromSchema(i)) + return nil, resp, err } - return images, resp, nil + + return allFromSchemaFunc(respBody.Images, ImageFromSchema), resp, nil } // All returns all images. @@ -219,31 +203,20 @@ func (c *ImageClient) All(ctx context.Context) ([]*Image, error) { // AllWithOpts returns all images for the given options. func (c *ImageClient) AllWithOpts(ctx context.Context, opts ImageListOpts) ([]*Image, error) { - allImages := []*Image{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Image, *Response, error) { opts.Page = page - images, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allImages = append(allImages, images...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allImages, nil } // Delete deletes an image. func (c *ImageClient) Delete(ctx context.Context, image *Image) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/images/%d", image.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/images/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, image.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // ImageUpdateOpts specifies options for updating an image. @@ -255,6 +228,11 @@ type ImageUpdateOpts struct { // Update updates an image. func (c *ImageClient) Update(ctx context.Context, image *Image, opts ImageUpdateOpts) (*Image, *Response, error) { + const opPath = "/images/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, image.ID) + reqBody := schema.ImageUpdateRequest{ Description: opts.Description, } @@ -264,22 +242,12 @@ func (c *ImageClient) Update(ctx context.Context, image *Image, opts ImageUpdate if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/images/%d", image.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ImageUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.ImageUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ImageFromSchema(respBody.Image), resp, nil } @@ -290,24 +258,19 @@ type ImageChangeProtectionOpts struct { // ChangeProtection changes the resource protection level of an image. func (c *ImageClient) ChangeProtection(ctx context.Context, image *Image, opts ImageChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/images/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, image.ID) + reqBody := schema.ImageActionChangeProtectionRequest{ Delete: opts.Delete, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/images/%d/actions/change_protection", image.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.ImageActionChangeProtectionResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ImageActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/interface_gen.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/interface_gen.go new file mode 100644 index 0000000000000..2ae8cecb497ca --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/interface_gen.go @@ -0,0 +1,22 @@ +package hcloud + +//go:generate go run github.com/vburenin/ifacemaker -f action.go -f action_watch.go -f action_waiter.go -s ActionClient -i IActionClient -p hcloud -o zz_action_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f action.go -s ResourceActionClient -i IResourceActionClient -p hcloud -o zz_resource_action_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f datacenter.go -s DatacenterClient -i IDatacenterClient -p hcloud -o zz_datacenter_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f floating_ip.go -s FloatingIPClient -i IFloatingIPClient -p hcloud -o zz_floating_ip_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f image.go -s ImageClient -i IImageClient -p hcloud -o zz_image_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f iso.go -s ISOClient -i IISOClient -p hcloud -o zz_iso_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f location.go -s LocationClient -i ILocationClient -p hcloud -o zz_location_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f network.go -s NetworkClient -i INetworkClient -p hcloud -o zz_network_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f pricing.go -s PricingClient -i IPricingClient -p hcloud -o zz_pricing_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f server.go -s ServerClient -i IServerClient -p hcloud -o zz_server_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f server_type.go -s ServerTypeClient -i IServerTypeClient -p hcloud -o zz_server_type_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f ssh_key.go -s SSHKeyClient -i ISSHKeyClient -p hcloud -o zz_ssh_key_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f volume.go -s VolumeClient -i IVolumeClient -p hcloud -o zz_volume_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f load_balancer.go -s LoadBalancerClient -i ILoadBalancerClient -p hcloud -o zz_load_balancer_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f load_balancer_type.go -s LoadBalancerTypeClient -i ILoadBalancerTypeClient -p hcloud -o zz_load_balancer_type_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f certificate.go -s CertificateClient -i ICertificateClient -p hcloud -o zz_certificate_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f firewall.go -s FirewallClient -i IFirewallClient -p hcloud -o zz_firewall_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f placement_group.go -s PlacementGroupClient -i IPlacementGroupClient -p hcloud -o zz_placement_group_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f rdns.go -s RDNSClient -i IRDNSClient -p hcloud -o zz_rdns_client_iface.go +//go:generate go run github.com/vburenin/ifacemaker -f primary_ip.go -s PrimaryIPClient -i IPrimaryIPClient -p hcloud -o zz_primary_ip_client_iface.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation/metrics.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/instrumentation/metrics.go similarity index 70% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation/metrics.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/instrumentation/metrics.go index aa57c7107c0af..4496d2b437781 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation/metrics.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/instrumentation/metrics.go @@ -1,6 +1,7 @@ package instrumentation import ( + "errors" "fmt" "net/http" "regexp" @@ -9,20 +10,27 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" + + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" ) type Instrumenter struct { subsystemIdentifier string // will be used as part of the metric name (hcloud__requests_total) - instrumentationRegistry *prometheus.Registry + instrumentationRegistry prometheus.Registerer } // New creates a new Instrumenter. The subsystemIdentifier will be used as part of the metric names (e.g. hcloud__requests_total). -func New(subsystemIdentifier string, instrumentationRegistry *prometheus.Registry) *Instrumenter { +func New(subsystemIdentifier string, instrumentationRegistry prometheus.Registerer) *Instrumenter { return &Instrumenter{subsystemIdentifier: subsystemIdentifier, instrumentationRegistry: instrumentationRegistry} } // InstrumentedRoundTripper returns an instrumented round tripper. -func (i *Instrumenter) InstrumentedRoundTripper() http.RoundTripper { +func (i *Instrumenter) InstrumentedRoundTripper(transport http.RoundTripper) http.RoundTripper { + // By default, http client would use DefaultTransport on nil, but we internally are relying on it being configured + if transport == nil { + transport = http.DefaultTransport + } + inFlightRequestsGauge := registerOrReuse( i.instrumentationRegistry, prometheus.NewGauge(prometheus.GaugeOpts{ @@ -57,7 +65,7 @@ func (i *Instrumenter) InstrumentedRoundTripper() http.RoundTripper { return promhttp.InstrumentRoundTripperInFlight(inFlightRequestsGauge, promhttp.InstrumentRoundTripperDuration(requestLatencyHistogram, i.instrumentRoundTripperEndpoint(requestsPerEndpointCounter, - http.DefaultTransport, + transport, ), ), ) @@ -73,8 +81,17 @@ func (i *Instrumenter) instrumentRoundTripperEndpoint(counter *prometheus.Counte return func(r *http.Request) (*http.Response, error) { resp, err := next.RoundTrip(r) if err == nil { - statusCode := strconv.Itoa(resp.StatusCode) - counter.WithLabelValues(statusCode, strings.ToLower(resp.Request.Method), preparePathForLabel(resp.Request.URL.Path)).Inc() + apiEndpoint := ctxutil.OpPath(r.Context()) + // If the request does not set the operation path, we must construct it. Happens e.g. for + // user crafted requests. + if apiEndpoint == "" { + apiEndpoint = preparePathForLabel(resp.Request.URL.Path) + } + counter.WithLabelValues( + strconv.Itoa(resp.StatusCode), + strings.ToLower(resp.Request.Method), + apiEndpoint, + ).Inc() } return resp, err @@ -84,12 +101,13 @@ func (i *Instrumenter) instrumentRoundTripperEndpoint(counter *prometheus.Counte // registerOrReuse will try to register the passed Collector, but in case a conflicting collector was already registered, // it will instead return that collector. Make sure to always use the collector return by this method. // Similar to [Registry.MustRegister] it will panic if any other error occurs. -func registerOrReuse[C prometheus.Collector](registry *prometheus.Registry, collector C) C { +func registerOrReuse[C prometheus.Collector](registry prometheus.Registerer, collector C) C { err := registry.Register(collector) if err != nil { + var arErr prometheus.AlreadyRegisteredError // If we get a AlreadyRegisteredError we can return the existing collector - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { - if existingCollector, ok := are.ExistingCollector.(C); ok { + if errors.As(err, &arErr) { + if existingCollector, ok := arErr.ExistingCollector.(C); ok { collector = existingCollector } else { panic("received incompatible existing collector") @@ -102,16 +120,16 @@ func registerOrReuse[C prometheus.Collector](registry *prometheus.Registry, coll return collector } +var pathLabelRegexp = regexp.MustCompile("[^a-z/_]+") + func preparePathForLabel(path string) string { path = strings.ToLower(path) - // replace all numbers and chars that are not a-z, / or _ - reg := regexp.MustCompile("[^a-z/_]+") - path = reg.ReplaceAllString(path, "") + // replace the /v1/ that indicated the API version + path, _ = strings.CutPrefix(path, "/v1") - // replace all artifacts of number replacement (//) - path = strings.ReplaceAll(path, "//", "/") + // replace all numbers and chars that are not a-z, / or _ + path = pathLabelRegexp.ReplaceAllString(path, "-") - // replace the /v/ that indicated the API version - return strings.Replace(path, "/v/", "/", 1) + return path } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/iso.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/iso.go similarity index 68% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/iso.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/iso.go index b4a4855f11a3a..2d66b52f00e9b 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/iso.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/iso.go @@ -4,15 +4,15 @@ import ( "context" "fmt" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // ISO represents an ISO image in the Hetzner Cloud. type ISO struct { - ID int + ID int64 Name string Description string Type ISOType @@ -39,41 +39,33 @@ type ISOClient struct { } // GetByID retrieves an ISO by its ID. -func (c *ISOClient) GetByID(ctx context.Context, id int) (*ISO, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/isos/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *ISOClient) GetByID(ctx context.Context, id int64) (*ISO, *Response, error) { + const opPath = "/isos/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.ISOGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ISOGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } return nil, resp, err } - return ISOFromSchema(body.ISO), resp, nil + + return ISOFromSchema(respBody.ISO), resp, nil } // GetByName retrieves an ISO by its name. func (c *ISOClient) GetByName(ctx context.Context, name string) (*ISO, *Response, error) { - if name == "" { - return nil, nil, nil - } - isos, response, err := c.List(ctx, ISOListOpts{Name: name}) - if len(isos) == 0 { - return nil, response, err - } - return isos[0], response, err + return firstByName(name, func() ([]*ISO, *Response, error) { + return c.List(ctx, ISOListOpts{Name: name}) + }) } // Get retrieves an ISO by its ID if the input can be parsed as an integer, otherwise it retrieves an ISO by its name. func (c *ISOClient) Get(ctx context.Context, idOrName string) (*ISO, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // ISOListOpts specifies options for listing isos. @@ -115,22 +107,17 @@ func (l ISOListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *ISOClient) List(ctx context.Context, opts ISOListOpts) ([]*ISO, *Response, error) { - path := "/isos?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/isos?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.ISOListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.ISOListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - isos := make([]*ISO, 0, len(body.ISOs)) - for _, i := range body.ISOs { - isos = append(isos, ISOFromSchema(i)) + return nil, resp, err } - return isos, resp, nil + + return allFromSchemaFunc(respBody.ISOs, ISOFromSchema), resp, nil } // All returns all ISOs. @@ -140,20 +127,8 @@ func (c *ISOClient) All(ctx context.Context) ([]*ISO, error) { // AllWithOpts returns all ISOs for the given options. func (c *ISOClient) AllWithOpts(ctx context.Context, opts ISOListOpts) ([]*ISO, error) { - allISOs := []*ISO{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*ISO, *Response, error) { opts.Page = page - isos, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allISOs = append(allISOs, isos...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allISOs, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/labels.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/labels.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/labels.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/labels.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/load_balancer.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/load_balancer.go similarity index 74% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/load_balancer.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/load_balancer.go index af440f1ffb925..f75f69d3d8be2 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/load_balancer.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/load_balancer.go @@ -1,22 +1,20 @@ package hcloud import ( - "bytes" "context" - "encoding/json" "fmt" "net" - "net/http" "net/url" "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // LoadBalancer represents a Load Balancer in the Hetzner Cloud. type LoadBalancer struct { - ID int + ID int64 Name string PublicNet LoadBalancerPublicNet PrivateNet []LoadBalancerPrivateNet @@ -200,26 +198,21 @@ type LoadBalancerProtection struct { // changeDNSPtr changes or resets the reverse DNS pointer for an IP address. // Pass a nil ptr to reset the reverse DNS pointer to its default value. func (lb *LoadBalancer) changeDNSPtr(ctx context.Context, client *Client, ip net.IP, ptr *string) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/change_dns_ptr" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, lb.ID) + reqBody := schema.LoadBalancerActionChangeDNSPtrRequest{ IP: ip.String(), DNSPtr: ptr, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/load_balancers/%d/actions/change_dns_ptr", lb.ID) - req, err := client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.LoadBalancerActionChangeDNSPtrResponse{} - resp, err := client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionChangeDNSPtrResponse](ctx, client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -242,42 +235,34 @@ type LoadBalancerClient struct { } // GetByID retrieves a Load Balancer by its ID. If the Load Balancer does not exist, nil is returned. -func (c *LoadBalancerClient) GetByID(ctx context.Context, id int) (*LoadBalancer, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/load_balancers/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *LoadBalancerClient) GetByID(ctx context.Context, id int64) (*LoadBalancer, *Response, error) { + const opPath = "/load_balancers/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.LoadBalancerGetResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, id) + + respBody, resp, err := getRequest[schema.LoadBalancerGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return LoadBalancerFromSchema(body.LoadBalancer), resp, nil + + return LoadBalancerFromSchema(respBody.LoadBalancer), resp, nil } // GetByName retrieves a Load Balancer by its name. If the Load Balancer does not exist, nil is returned. func (c *LoadBalancerClient) GetByName(ctx context.Context, name string) (*LoadBalancer, *Response, error) { - if name == "" { - return nil, nil, nil - } - LoadBalancer, response, err := c.List(ctx, LoadBalancerListOpts{Name: name}) - if len(LoadBalancer) == 0 { - return nil, response, err - } - return LoadBalancer[0], response, err + return firstByName(name, func() ([]*LoadBalancer, *Response, error) { + return c.List(ctx, LoadBalancerListOpts{Name: name}) + }) } // Get retrieves a Load Balancer by its ID if the input can be parsed as an integer, otherwise it // retrieves a Load Balancer by its name. If the Load Balancer does not exist, nil is returned. func (c *LoadBalancerClient) Get(ctx context.Context, idOrName string) (*LoadBalancer, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, id) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // LoadBalancerListOpts specifies options for listing Load Balancers. @@ -303,22 +288,17 @@ func (l LoadBalancerListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *LoadBalancerClient) List(ctx context.Context, opts LoadBalancerListOpts) ([]*LoadBalancer, *Response, error) { - path := "/load_balancers?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/load_balancers?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.LoadBalancerListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.LoadBalancerListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - LoadBalancers := make([]*LoadBalancer, 0, len(body.LoadBalancers)) - for _, s := range body.LoadBalancers { - LoadBalancers = append(LoadBalancers, LoadBalancerFromSchema(s)) + return nil, resp, err } - return LoadBalancers, resp, nil + + return allFromSchemaFunc(respBody.LoadBalancers, LoadBalancerFromSchema), resp, nil } // All returns all Load Balancers. @@ -328,22 +308,10 @@ func (c *LoadBalancerClient) All(ctx context.Context) ([]*LoadBalancer, error) { // AllWithOpts returns all Load Balancers for the given options. func (c *LoadBalancerClient) AllWithOpts(ctx context.Context, opts LoadBalancerListOpts) ([]*LoadBalancer, error) { - allLoadBalancers := []*LoadBalancer{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*LoadBalancer, *Response, error) { opts.Page = page - LoadBalancers, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allLoadBalancers = append(allLoadBalancers, LoadBalancers...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allLoadBalancers, nil } // LoadBalancerUpdateOpts specifies options for updating a Load Balancer. @@ -354,6 +322,11 @@ type LoadBalancerUpdateOpts struct { // Update updates a Load Balancer. func (c *LoadBalancerClient) Update(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerUpdateOpts) (*LoadBalancer, *Response, error) { + const opPath = "/load_balancers/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := schema.LoadBalancerUpdateRequest{} if opts.Name != "" { reqBody.Name = &opts.Name @@ -361,22 +334,12 @@ func (c *LoadBalancerClient) Update(ctx context.Context, loadBalancer *LoadBalan if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/load_balancers/%d", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.LoadBalancerUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return LoadBalancerFromSchema(respBody.LoadBalancer), resp, nil } @@ -472,73 +435,61 @@ type LoadBalancerCreateResult struct { // Create creates a new Load Balancer. func (c *LoadBalancerClient) Create(ctx context.Context, opts LoadBalancerCreateOpts) (LoadBalancerCreateResult, *Response, error) { + const opPath = "/load_balancers" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := LoadBalancerCreateResult{} + + reqPath := opPath + reqBody := loadBalancerCreateOptsToSchema(opts) - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return LoadBalancerCreateResult{}, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/load_balancers", bytes.NewReader(reqBodyData)) - if err != nil { - return LoadBalancerCreateResult{}, nil, err - } - respBody := schema.LoadBalancerCreateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return LoadBalancerCreateResult{}, resp, err + return result, resp, err } - return LoadBalancerCreateResult{ - LoadBalancer: LoadBalancerFromSchema(respBody.LoadBalancer), - Action: ActionFromSchema(respBody.Action), - }, resp, nil + + result.LoadBalancer = LoadBalancerFromSchema(respBody.LoadBalancer) + result.Action = ActionFromSchema(respBody.Action) + + return result, resp, nil } // Delete deletes a Load Balancer. func (c *LoadBalancerClient) Delete(ctx context.Context, loadBalancer *LoadBalancer) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/load_balancers/%d", loadBalancer.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/load_balancers/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } func (c *LoadBalancerClient) addTarget(ctx context.Context, loadBalancer *LoadBalancer, reqBody schema.LoadBalancerActionAddTargetRequest) (*Action, *Response, error) { - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/load_balancers/%d/actions/add_target" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/load_balancers/%d/actions/add_target", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) - var respBody schema.LoadBalancerActionAddTargetResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionAddTargetResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } func (c *LoadBalancerClient) removeTarget(ctx context.Context, loadBalancer *LoadBalancer, reqBody schema.LoadBalancerActionRemoveTargetRequest) (*Action, *Response, error) { - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/load_balancers/%d/actions/remove_target" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/load_balancers/%d/actions/remove_target", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) - var respBody schema.LoadBalancerActionRemoveTargetResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionRemoveTargetResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -671,23 +622,18 @@ type LoadBalancerAddServiceOptsHealthCheckHTTP struct { // AddService adds a service to a Load Balancer. func (c *LoadBalancerClient) AddService(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddServiceOpts) (*Action, *Response, error) { - reqBody := loadBalancerAddServiceOptsToSchema(opts) - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/load_balancers/%d/actions/add_service" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/load_balancers/%d/actions/add_service", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) - var respBody schema.LoadBalancerActionAddServiceResponse - resp, err := c.client.Do(req, &respBody) + reqBody := loadBalancerAddServiceOptsToSchema(opts) + + respBody, resp, err := postRequest[schema.LoadBalancerActionAddServiceResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -732,48 +678,38 @@ type LoadBalancerUpdateServiceOptsHealthCheckHTTP struct { // UpdateService updates a Load Balancer service. func (c *LoadBalancerClient) UpdateService(ctx context.Context, loadBalancer *LoadBalancer, listenPort int, opts LoadBalancerUpdateServiceOpts) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/update_service" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := loadBalancerUpdateServiceOptsToSchema(opts) reqBody.ListenPort = listenPort - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/load_balancers/%d/actions/update_service", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - var respBody schema.LoadBalancerActionUpdateServiceResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionUpdateServiceResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // DeleteService deletes a Load Balancer service. func (c *LoadBalancerClient) DeleteService(ctx context.Context, loadBalancer *LoadBalancer, listenPort int) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/delete_service" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := schema.LoadBalancerDeleteServiceRequest{ ListenPort: listenPort, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/load_balancers/%d/actions/delete_service", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.LoadBalancerDeleteServiceResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerDeleteServiceResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -784,26 +720,21 @@ type LoadBalancerChangeProtectionOpts struct { // ChangeProtection changes the resource protection level of a Load Balancer. func (c *LoadBalancerClient) ChangeProtection(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := schema.LoadBalancerActionChangeProtectionRequest{ Delete: opts.Delete, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/load_balancers/%d/actions/change_protection", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerActionChangeProtectionResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // LoadBalancerChangeAlgorithmOpts specifies options for changing the algorithm of a Load Balancer. @@ -813,26 +744,21 @@ type LoadBalancerChangeAlgorithmOpts struct { // ChangeAlgorithm changes the algorithm of a Load Balancer. func (c *LoadBalancerClient) ChangeAlgorithm(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeAlgorithmOpts) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/change_algorithm" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := schema.LoadBalancerActionChangeAlgorithmRequest{ Type: string(opts.Type), } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/load_balancers/%d/actions/change_algorithm", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerActionChangeAlgorithmResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionChangeAlgorithmResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // LoadBalancerAttachToNetworkOpts specifies options for attaching a Load Balancer to a network. @@ -843,29 +769,24 @@ type LoadBalancerAttachToNetworkOpts struct { // AttachToNetwork attaches a Load Balancer to a network. func (c *LoadBalancerClient) AttachToNetwork(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAttachToNetworkOpts) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/attach_to_network" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := schema.LoadBalancerActionAttachToNetworkRequest{ Network: opts.Network.ID, } if opts.IP != nil { reqBody.IP = Ptr(opts.IP.String()) } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/load_balancers/%d/actions/attach_to_network", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerActionAttachToNetworkResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionAttachToNetworkResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // LoadBalancerDetachFromNetworkOpts specifies options for detaching a Load Balancer from a network. @@ -875,56 +796,51 @@ type LoadBalancerDetachFromNetworkOpts struct { // DetachFromNetwork detaches a Load Balancer from a network. func (c *LoadBalancerClient) DetachFromNetwork(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerDetachFromNetworkOpts) (*Action, *Response, error) { + const opPath = "/load_balancers/%d/actions/detach_from_network" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + reqBody := schema.LoadBalancerActionDetachFromNetworkRequest{ Network: opts.Network.ID, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/load_balancers/%d/actions/detach_from_network", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerActionDetachFromNetworkResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionDetachFromNetworkResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // EnablePublicInterface enables the Load Balancer's public network interface. func (c *LoadBalancerClient) EnablePublicInterface(ctx context.Context, loadBalancer *LoadBalancer) (*Action, *Response, error) { - path := fmt.Sprintf("/load_balancers/%d/actions/enable_public_interface", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerActionEnablePublicInterfaceResponse{} - resp, err := c.client.Do(req, &respBody) + const opPath = "/load_balancers/%d/actions/enable_public_interface" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + + respBody, resp, err := postRequest[schema.LoadBalancerActionEnablePublicInterfaceResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // DisablePublicInterface disables the Load Balancer's public network interface. func (c *LoadBalancerClient) DisablePublicInterface(ctx context.Context, loadBalancer *LoadBalancer) (*Action, *Response, error) { - path := fmt.Sprintf("/load_balancers/%d/actions/disable_public_interface", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } - respBody := schema.LoadBalancerActionDisablePublicInterfaceResponse{} - resp, err := c.client.Do(req, &respBody) + const opPath = "/load_balancers/%d/actions/disable_public_interface" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + + respBody, resp, err := postRequest[schema.LoadBalancerActionDisablePublicInterfaceResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // LoadBalancerChangeTypeOpts specifies options for changing a Load Balancer's type. @@ -934,28 +850,21 @@ type LoadBalancerChangeTypeOpts struct { // ChangeType changes a Load Balancer's type. func (c *LoadBalancerClient) ChangeType(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeTypeOpts) (*Action, *Response, error) { - reqBody := schema.LoadBalancerActionChangeTypeRequest{} - if opts.LoadBalancerType.ID != 0 { - reqBody.LoadBalancerType = opts.LoadBalancerType.ID - } else { - reqBody.LoadBalancerType = opts.LoadBalancerType.Name - } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/load_balancers/%d/actions/change_type" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/load_balancers/%d/actions/change_type", loadBalancer.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err + reqPath := fmt.Sprintf(opPath, loadBalancer.ID) + + reqBody := schema.LoadBalancerActionChangeTypeRequest{} + if opts.LoadBalancerType.ID != 0 || opts.LoadBalancerType.Name != "" { + reqBody.LoadBalancerType = schema.IDOrName{ID: opts.LoadBalancerType.ID, Name: opts.LoadBalancerType.Name} } - respBody := schema.LoadBalancerActionChangeTypeResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.LoadBalancerActionChangeTypeResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -980,32 +889,34 @@ type LoadBalancerGetMetricsOpts struct { Step int } -func (o *LoadBalancerGetMetricsOpts) addQueryParams(req *http.Request) error { - query := req.URL.Query() - +func (o LoadBalancerGetMetricsOpts) Validate() error { if len(o.Types) == 0 { - return fmt.Errorf("no metric types specified") + return missingField(o, "Types") + } + if o.Start.IsZero() { + return missingField(o, "Start") + } + if o.End.IsZero() { + return missingField(o, "End") } + return nil +} + +func (o LoadBalancerGetMetricsOpts) values() url.Values { + query := url.Values{} + for _, typ := range o.Types { query.Add("type", string(typ)) } - if o.Start.IsZero() { - return fmt.Errorf("no start time specified") - } query.Add("start", o.Start.Format(time.RFC3339)) - - if o.End.IsZero() { - return fmt.Errorf("no end time specified") - } query.Add("end", o.End.Format(time.RFC3339)) if o.Step > 0 { query.Add("step", strconv.Itoa(o.Step)) } - req.URL.RawQuery = query.Encode() - return nil + return query } // LoadBalancerMetrics contains the metrics requested for a Load Balancer. @@ -1024,31 +935,32 @@ type LoadBalancerMetricsValue struct { // GetMetrics obtains metrics for a Load Balancer. func (c *LoadBalancerClient) GetMetrics( - ctx context.Context, lb *LoadBalancer, opts LoadBalancerGetMetricsOpts, + ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerGetMetricsOpts, ) (*LoadBalancerMetrics, *Response, error) { - var respBody schema.LoadBalancerGetMetricsResponse + const opPath = "/load_balancers/%d/metrics?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - if lb == nil { - return nil, nil, fmt.Errorf("illegal argument: load balancer is nil") + if loadBalancer == nil { + return nil, nil, missingArgument("loadBalancer", loadBalancer) } - path := fmt.Sprintf("/load_balancers/%d/metrics", lb.ID) - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, fmt.Errorf("new request: %v", err) - } - if err := opts.addQueryParams(req); err != nil { - return nil, nil, fmt.Errorf("add query params: %v", err) + if err := opts.Validate(); err != nil { + return nil, nil, err } - resp, err := c.client.Do(req, &respBody) + + reqPath := fmt.Sprintf(opPath, loadBalancer.ID, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.LoadBalancerGetMetricsResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, fmt.Errorf("get metrics: %v", err) + return nil, resp, err } - ms, err := loadBalancerMetricsFromSchema(&respBody) + + metrics, err := loadBalancerMetricsFromSchema(&respBody) if err != nil { - return nil, nil, fmt.Errorf("convert response body: %v", err) + return nil, nil, fmt.Errorf("convert response body: %w", err) } - return ms, resp, nil + + return metrics, resp, nil } // ChangeDNSPtr changes or resets the reverse DNS pointer for a Load Balancer. diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/load_balancer_type.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/load_balancer_type.go similarity index 61% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/load_balancer_type.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/load_balancer_type.go index 9a32e87d029c5..38e59482011e9 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/load_balancer_type.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/load_balancer_type.go @@ -6,12 +6,13 @@ import ( "net/url" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // LoadBalancerType represents a LoadBalancer type in the Hetzner Cloud. type LoadBalancerType struct { - ID int + ID int64 Name string Description string MaxConnections int @@ -19,6 +20,7 @@ type LoadBalancerType struct { MaxTargets int MaxAssignedCertificates int Pricings []LoadBalancerTypeLocationPricing + Deprecated *string } // LoadBalancerTypeClient is a client for the Load Balancer types API. @@ -27,40 +29,35 @@ type LoadBalancerTypeClient struct { } // GetByID retrieves a Load Balancer type by its ID. If the Load Balancer type does not exist, nil is returned. -func (c *LoadBalancerTypeClient) GetByID(ctx context.Context, id int) (*LoadBalancerType, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/load_balancer_types/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *LoadBalancerTypeClient) GetByID(ctx context.Context, id int64) (*LoadBalancerType, *Response, error) { + const opPath = "/load_balancer_types/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.LoadBalancerTypeGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.LoadBalancerTypeGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return LoadBalancerTypeFromSchema(body.LoadBalancerType), resp, nil + + return LoadBalancerTypeFromSchema(respBody.LoadBalancerType), resp, nil } // GetByName retrieves a Load Balancer type by its name. If the Load Balancer type does not exist, nil is returned. func (c *LoadBalancerTypeClient) GetByName(ctx context.Context, name string) (*LoadBalancerType, *Response, error) { - if name == "" { - return nil, nil, nil - } - LoadBalancerTypes, response, err := c.List(ctx, LoadBalancerTypeListOpts{Name: name}) - if len(LoadBalancerTypes) == 0 { - return nil, response, err - } - return LoadBalancerTypes[0], response, err + return firstByName(name, func() ([]*LoadBalancerType, *Response, error) { + return c.List(ctx, LoadBalancerTypeListOpts{Name: name}) + }) } // Get retrieves a Load Balancer type by its ID if the input can be parsed as an integer, otherwise it // retrieves a Load Balancer type by its name. If the Load Balancer type does not exist, nil is returned. func (c *LoadBalancerTypeClient) Get(ctx context.Context, idOrName string) (*LoadBalancerType, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) + if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { + return c.GetByID(ctx, id) } return c.GetByName(ctx, idOrName) } @@ -88,22 +85,17 @@ func (l LoadBalancerTypeListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *LoadBalancerTypeClient) List(ctx context.Context, opts LoadBalancerTypeListOpts) ([]*LoadBalancerType, *Response, error) { - path := "/load_balancer_types?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/load_balancer_types?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.LoadBalancerTypeListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.LoadBalancerTypeListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - LoadBalancerTypes := make([]*LoadBalancerType, 0, len(body.LoadBalancerTypes)) - for _, s := range body.LoadBalancerTypes { - LoadBalancerTypes = append(LoadBalancerTypes, LoadBalancerTypeFromSchema(s)) + return nil, resp, err } - return LoadBalancerTypes, resp, nil + + return allFromSchemaFunc(respBody.LoadBalancerTypes, LoadBalancerTypeFromSchema), resp, nil } // All returns all Load Balancer types. @@ -113,20 +105,8 @@ func (c *LoadBalancerTypeClient) All(ctx context.Context) ([]*LoadBalancerType, // AllWithOpts returns all Load Balancer types for the given options. func (c *LoadBalancerTypeClient) AllWithOpts(ctx context.Context, opts LoadBalancerTypeListOpts) ([]*LoadBalancerType, error) { - allLoadBalancerTypes := []*LoadBalancerType{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*LoadBalancerType, *Response, error) { opts.Page = page - LoadBalancerTypes, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allLoadBalancerTypes = append(allLoadBalancerTypes, LoadBalancerTypes...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allLoadBalancerTypes, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/location.go similarity index 60% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/location.go index 6b8cbec9b634f..4e568927d87d0 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/location.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/location.go @@ -6,12 +6,13 @@ import ( "net/url" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Location represents a location in the Hetzner Cloud. type Location struct { - ID int + ID int64 Name string Description string Country string @@ -27,40 +28,35 @@ type LocationClient struct { } // GetByID retrieves a location by its ID. If the location does not exist, nil is returned. -func (c *LocationClient) GetByID(ctx context.Context, id int) (*Location, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/locations/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *LocationClient) GetByID(ctx context.Context, id int64) (*Location, *Response, error) { + const opPath = "/locations/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.LocationGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.LocationGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } return nil, resp, err } - return LocationFromSchema(body.Location), resp, nil + + return LocationFromSchema(respBody.Location), resp, nil } // GetByName retrieves an location by its name. If the location does not exist, nil is returned. func (c *LocationClient) GetByName(ctx context.Context, name string) (*Location, *Response, error) { - if name == "" { - return nil, nil, nil - } - locations, response, err := c.List(ctx, LocationListOpts{Name: name}) - if len(locations) == 0 { - return nil, response, err - } - return locations[0], response, err + return firstByName(name, func() ([]*Location, *Response, error) { + return c.List(ctx, LocationListOpts{Name: name}) + }) } // Get retrieves a location by its ID if the input can be parsed as an integer, otherwise it // retrieves a location by its name. If the location does not exist, nil is returned. func (c *LocationClient) Get(ctx context.Context, idOrName string) (*Location, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) + if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { + return c.GetByID(ctx, id) } return c.GetByName(ctx, idOrName) } @@ -88,22 +84,17 @@ func (l LocationListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *LocationClient) List(ctx context.Context, opts LocationListOpts) ([]*Location, *Response, error) { - path := "/locations?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/locations?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.LocationListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.LocationListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - locations := make([]*Location, 0, len(body.Locations)) - for _, i := range body.Locations { - locations = append(locations, LocationFromSchema(i)) + return nil, resp, err } - return locations, resp, nil + + return allFromSchemaFunc(respBody.Locations, LocationFromSchema), resp, nil } // All returns all locations. @@ -113,20 +104,8 @@ func (c *LocationClient) All(ctx context.Context) ([]*Location, error) { // AllWithOpts returns all locations for the given options. func (c *LocationClient) AllWithOpts(ctx context.Context, opts LocationListOpts) ([]*Location, error) { - allLocations := []*Location{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Location, *Response, error) { opts.Page = page - locations, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allLocations = append(allLocations, locations...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allLocations, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/metadata/client.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/metadata/client.go similarity index 83% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/metadata/client.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/metadata/client.go index 52e5876aca6cd..f5ddeffc165dc 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/metadata/client.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/metadata/client.go @@ -1,6 +1,8 @@ package metadata import ( + "bytes" + "context" "fmt" "io" "net" @@ -11,7 +13,8 @@ import ( "github.com/prometheus/client_golang/prometheus" - "github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/internal/instrumentation" ) const Endpoint = "http://169.254.169.254/hetzner/v1/metadata" @@ -22,7 +25,7 @@ type Client struct { timeout time.Duration httpClient *http.Client - instrumentationRegistry *prometheus.Registry + instrumentationRegistry prometheus.Registerer } // A ClientOption is used to configure a [Client]. @@ -43,7 +46,7 @@ func WithHTTPClient(httpClient *http.Client) ClientOption { } // WithInstrumentation configures a [Client] to collect metrics about the performed HTTP requests. -func WithInstrumentation(registry *prometheus.Registry) ClientOption { +func WithInstrumentation(registry prometheus.Registerer) ClientOption { return func(client *Client) { client.instrumentationRegistry = registry } @@ -72,24 +75,33 @@ func NewClient(options ...ClientOption) *Client { if client.instrumentationRegistry != nil { i := instrumentation.New("metadata", client.instrumentationRegistry) - client.httpClient.Transport = i.InstrumentedRoundTripper() + client.httpClient.Transport = i.InstrumentedRoundTripper(client.httpClient.Transport) } return client } // get executes an HTTP request against the API. func (c *Client) get(path string) (string, error) { - url := c.endpoint + path - resp, err := c.httpClient.Get(url) + ctx := ctxutil.SetOpPath(context.Background(), path) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.endpoint+path, http.NoBody) + if err != nil { + return "", err + } + + resp, err := c.httpClient.Do(req) if err != nil { return "", err } + defer resp.Body.Close() bodyBytes, err := io.ReadAll(resp.Body) if err != nil { return "", err } - body := string(bodyBytes) + + body := string(bytes.TrimSpace(bodyBytes)) + if resp.StatusCode < 200 || resp.StatusCode >= 300 { return body, fmt.Errorf("response status was %d", resp.StatusCode) } @@ -115,12 +127,12 @@ func (c *Client) Hostname() (string, error) { } // InstanceID returns the ID of the server that did the request to the Metadata server. -func (c *Client) InstanceID() (int, error) { +func (c *Client) InstanceID() (int64, error) { resp, err := c.get("/instance-id") if err != nil { return 0, err } - return strconv.Atoi(resp) + return strconv.ParseInt(resp, 10, 64) } // PublicIPv4 returns the Public IPv4 of the server that did the request to the Metadata server. diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/network.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go similarity index 64% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/network.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go index 7e6b9e446e070..f33f25309ba5d 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/network.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go @@ -1,17 +1,14 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // NetworkZone specifies a network zone. @@ -30,22 +27,30 @@ type NetworkSubnetType string // List of available network subnet types. const ( - NetworkSubnetTypeCloud NetworkSubnetType = "cloud" - NetworkSubnetTypeServer NetworkSubnetType = "server" + // Used to connect cloud servers and load balancers. + NetworkSubnetTypeCloud NetworkSubnetType = "cloud" + // Used to connect cloud servers and load balancers. + // + // Deprecated: Use [NetworkSubnetTypeCloud] instead. + NetworkSubnetTypeServer NetworkSubnetType = "server" + // Used to connect cloud servers and load balancers with dedicated servers. + // + // See https://docs.hetzner.com/cloud/networks/connect-dedi-vswitch/ NetworkSubnetTypeVSwitch NetworkSubnetType = "vswitch" ) // Network represents a network in the Hetzner Cloud. type Network struct { - ID int - Name string - Created time.Time - IPRange *net.IPNet - Subnets []NetworkSubnet - Routes []NetworkRoute - Servers []*Server - Protection NetworkProtection - Labels map[string]string + ID int64 + Name string + Created time.Time + IPRange *net.IPNet + Subnets []NetworkSubnet + Routes []NetworkRoute + Servers []*Server + LoadBalancers []*LoadBalancer + Protection NetworkProtection + Labels map[string]string // ExposeRoutesToVSwitch indicates if the routes from this network should be exposed to the vSwitch connection. ExposeRoutesToVSwitch bool @@ -57,7 +62,7 @@ type NetworkSubnet struct { IPRange *net.IPNet NetworkZone NetworkZone Gateway net.IP - VSwitchID int + VSwitchID int64 } // NetworkRoute represents a route of a network. @@ -78,42 +83,34 @@ type NetworkClient struct { } // GetByID retrieves a network by its ID. If the network does not exist, nil is returned. -func (c *NetworkClient) GetByID(ctx context.Context, id int) (*Network, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/networks/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *NetworkClient) GetByID(ctx context.Context, id int64) (*Network, *Response, error) { + const opPath = "/networks/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.NetworkGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.NetworkGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return NetworkFromSchema(body.Network), resp, nil + + return NetworkFromSchema(respBody.Network), resp, nil } // GetByName retrieves a network by its name. If the network does not exist, nil is returned. func (c *NetworkClient) GetByName(ctx context.Context, name string) (*Network, *Response, error) { - if name == "" { - return nil, nil, nil - } - Networks, response, err := c.List(ctx, NetworkListOpts{Name: name}) - if len(Networks) == 0 { - return nil, response, err - } - return Networks[0], response, err + return firstByName(name, func() ([]*Network, *Response, error) { + return c.List(ctx, NetworkListOpts{Name: name}) + }) } // Get retrieves a network by its ID if the input can be parsed as an integer, otherwise it // retrieves a network by its name. If the network does not exist, nil is returned. func (c *NetworkClient) Get(ctx context.Context, idOrName string) (*Network, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // NetworkListOpts specifies options for listing networks. @@ -139,22 +136,17 @@ func (l NetworkListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *NetworkClient) List(ctx context.Context, opts NetworkListOpts) ([]*Network, *Response, error) { - path := "/networks?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/networks?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.NetworkListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.NetworkListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - Networks := make([]*Network, 0, len(body.Networks)) - for _, s := range body.Networks { - Networks = append(Networks, NetworkFromSchema(s)) + return nil, resp, err } - return Networks, resp, nil + + return allFromSchemaFunc(respBody.Networks, NetworkFromSchema), resp, nil } // All returns all networks. @@ -164,31 +156,20 @@ func (c *NetworkClient) All(ctx context.Context) ([]*Network, error) { // AllWithOpts returns all networks for the given options. func (c *NetworkClient) AllWithOpts(ctx context.Context, opts NetworkListOpts) ([]*Network, error) { - allNetworks := []*Network{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Network, *Response, error) { opts.Page = page - Networks, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allNetworks = append(allNetworks, Networks...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allNetworks, nil } // Delete deletes a network. func (c *NetworkClient) Delete(ctx context.Context, network *Network) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/networks/%d", network.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/networks/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // NetworkUpdateOpts specifies options for updating a network. @@ -202,6 +183,11 @@ type NetworkUpdateOpts struct { // Update updates a network. func (c *NetworkClient) Update(ctx context.Context, network *Network, opts NetworkUpdateOpts) (*Network, *Response, error) { + const opPath = "/networks/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkUpdateRequest{ Name: opts.Name, } @@ -212,22 +198,11 @@ func (c *NetworkClient) Update(ctx context.Context, network *Network, opts Netwo reqBody.ExposeRoutesToVSwitch = opts.ExposeRoutesToVSwitch } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/networks/%d", network.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.NetworkUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.NetworkUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return NetworkFromSchema(respBody.Network), resp, nil } @@ -246,16 +221,21 @@ type NetworkCreateOpts struct { // Validate checks if options are valid. func (o NetworkCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } if o.IPRange == nil || o.IPRange.String() == "" { - return errors.New("missing IP range") + return missingField(o, "IPRange") } return nil } // Create creates a new network. func (c *NetworkClient) Create(ctx context.Context, opts NetworkCreateOpts) (*Network, *Response, error) { + const opPath = "/networks" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := opPath + if err := opts.Validate(); err != nil { return nil, nil, err } @@ -284,20 +264,12 @@ func (c *NetworkClient) Create(ctx context.Context, opts NetworkCreateOpts) (*Ne if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/networks", bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.NetworkCreateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return NetworkFromSchema(respBody.Network), resp, nil } @@ -308,25 +280,20 @@ type NetworkChangeIPRangeOpts struct { // ChangeIPRange changes the IP range of a network. func (c *NetworkClient) ChangeIPRange(ctx context.Context, network *Network, opts NetworkChangeIPRangeOpts) (*Action, *Response, error) { + const opPath = "/networks/%d/actions/change_ip_range" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkActionChangeIPRangeRequest{ IPRange: opts.IPRange.String(), } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/networks/%d/actions/change_ip_range", network.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.NetworkActionChangeIPRangeResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkActionChangeIPRangeResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -337,6 +304,11 @@ type NetworkAddSubnetOpts struct { // AddSubnet adds a subnet to a network. func (c *NetworkClient) AddSubnet(ctx context.Context, network *Network, opts NetworkAddSubnetOpts) (*Action, *Response, error) { + const opPath = "/networks/%d/actions/add_subnet" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkActionAddSubnetRequest{ Type: string(opts.Subnet.Type), NetworkZone: string(opts.Subnet.NetworkZone), @@ -347,22 +319,12 @@ func (c *NetworkClient) AddSubnet(ctx context.Context, network *Network, opts Ne if opts.Subnet.VSwitchID != 0 { reqBody.VSwitchID = opts.Subnet.VSwitchID } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/networks/%d/actions/add_subnet", network.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.NetworkActionAddSubnetResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkActionAddSubnetResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -373,25 +335,20 @@ type NetworkDeleteSubnetOpts struct { // DeleteSubnet deletes a subnet from a network. func (c *NetworkClient) DeleteSubnet(ctx context.Context, network *Network, opts NetworkDeleteSubnetOpts) (*Action, *Response, error) { + const opPath = "/networks/%d/actions/delete_subnet" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkActionDeleteSubnetRequest{ IPRange: opts.Subnet.IPRange.String(), } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/networks/%d/actions/delete_subnet", network.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.NetworkActionDeleteSubnetResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkActionDeleteSubnetResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -402,26 +359,21 @@ type NetworkAddRouteOpts struct { // AddRoute adds a route to a network. func (c *NetworkClient) AddRoute(ctx context.Context, network *Network, opts NetworkAddRouteOpts) (*Action, *Response, error) { + const opPath = "/networks/%d/actions/add_route" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkActionAddRouteRequest{ Destination: opts.Route.Destination.String(), Gateway: opts.Route.Gateway.String(), } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/networks/%d/actions/add_route", network.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.NetworkActionAddSubnetResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkActionAddRouteResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -432,26 +384,21 @@ type NetworkDeleteRouteOpts struct { // DeleteRoute deletes a route from a network. func (c *NetworkClient) DeleteRoute(ctx context.Context, network *Network, opts NetworkDeleteRouteOpts) (*Action, *Response, error) { + const opPath = "/networks/%d/actions/delete_route" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkActionDeleteRouteRequest{ Destination: opts.Route.Destination.String(), Gateway: opts.Route.Gateway.String(), } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/networks/%d/actions/delete_route", network.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.NetworkActionDeleteSubnetResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkActionDeleteRouteResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -462,24 +409,19 @@ type NetworkChangeProtectionOpts struct { // ChangeProtection changes the resource protection level of a network. func (c *NetworkClient) ChangeProtection(ctx context.Context, network *Network, opts NetworkChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/networks/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, network.ID) + reqBody := schema.NetworkActionChangeProtectionRequest{ Delete: opts.Delete, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/networks/%d/actions/change_protection", network.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.NetworkActionChangeProtectionResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.NetworkActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/placement_group.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/placement_group.go similarity index 60% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/placement_group.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/placement_group.go index 3eb277f2101ae..9176b3d2a5bf5 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/placement_group.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/placement_group.go @@ -1,25 +1,22 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // PlacementGroup represents a Placement Group in the Hetzner Cloud. type PlacementGroup struct { - ID int + ID int64 Name string Labels map[string]string Created time.Time - Servers []int + Servers []int64 Type PlacementGroupType } @@ -37,42 +34,34 @@ type PlacementGroupClient struct { } // GetByID retrieves a PlacementGroup by its ID. If the PlacementGroup does not exist, nil is returned. -func (c *PlacementGroupClient) GetByID(ctx context.Context, id int) (*PlacementGroup, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/placement_groups/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *PlacementGroupClient) GetByID(ctx context.Context, id int64) (*PlacementGroup, *Response, error) { + const opPath = "/placement_groups/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.PlacementGroupGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.PlacementGroupGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return PlacementGroupFromSchema(body.PlacementGroup), resp, nil + + return PlacementGroupFromSchema(respBody.PlacementGroup), resp, nil } // GetByName retrieves a PlacementGroup by its name. If the PlacementGroup does not exist, nil is returned. func (c *PlacementGroupClient) GetByName(ctx context.Context, name string) (*PlacementGroup, *Response, error) { - if name == "" { - return nil, nil, nil - } - placementGroups, response, err := c.List(ctx, PlacementGroupListOpts{Name: name}) - if len(placementGroups) == 0 { - return nil, response, err - } - return placementGroups[0], response, err + return firstByName(name, func() ([]*PlacementGroup, *Response, error) { + return c.List(ctx, PlacementGroupListOpts{Name: name}) + }) } // Get retrieves a PlacementGroup by its ID if the input can be parsed as an integer, otherwise it // retrieves a PlacementGroup by its name. If the PlacementGroup does not exist, nil is returned. func (c *PlacementGroupClient) Get(ctx context.Context, idOrName string) (*PlacementGroup, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // PlacementGroupListOpts specifies options for listing PlacementGroup. @@ -102,22 +91,17 @@ func (l PlacementGroupListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *PlacementGroupClient) List(ctx context.Context, opts PlacementGroupListOpts) ([]*PlacementGroup, *Response, error) { - path := "/placement_groups?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/placement_groups?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.PlacementGroupListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.PlacementGroupListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - placementGroups := make([]*PlacementGroup, 0, len(body.PlacementGroups)) - for _, g := range body.PlacementGroups { - placementGroups = append(placementGroups, PlacementGroupFromSchema(g)) + return nil, resp, err } - return placementGroups, resp, nil + + return allFromSchemaFunc(respBody.PlacementGroups, PlacementGroupFromSchema), resp, nil } // All returns all PlacementGroups. @@ -133,22 +117,10 @@ func (c *PlacementGroupClient) All(ctx context.Context) ([]*PlacementGroup, erro // AllWithOpts returns all PlacementGroups for the given options. func (c *PlacementGroupClient) AllWithOpts(ctx context.Context, opts PlacementGroupListOpts) ([]*PlacementGroup, error) { - allPlacementGroups := []*PlacementGroup{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*PlacementGroup, *Response, error) { opts.Page = page - placementGroups, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allPlacementGroups = append(allPlacementGroups, placementGroups...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allPlacementGroups, nil } // PlacementGroupCreateOpts specifies options for creating a new PlacementGroup. @@ -161,7 +133,7 @@ type PlacementGroupCreateOpts struct { // Validate checks if options are valid. func (o PlacementGroupCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } return nil } @@ -174,27 +146,25 @@ type PlacementGroupCreateResult struct { // Create creates a new PlacementGroup. func (c *PlacementGroupClient) Create(ctx context.Context, opts PlacementGroupCreateOpts) (PlacementGroupCreateResult, *Response, error) { + const opPath = "/placement_groups" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := PlacementGroupCreateResult{} + + reqPath := opPath + if err := opts.Validate(); err != nil { - return PlacementGroupCreateResult{}, nil, err + return result, nil, err } + reqBody := placementGroupCreateOptsToSchema(opts) - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return PlacementGroupCreateResult{}, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/placement_groups", bytes.NewReader(reqBodyData)) - if err != nil { - return PlacementGroupCreateResult{}, nil, err - } - respBody := schema.PlacementGroupCreateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.PlacementGroupCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return PlacementGroupCreateResult{}, nil, err - } - result := PlacementGroupCreateResult{ - PlacementGroup: PlacementGroupFromSchema(respBody.PlacementGroup), + return result, resp, err } + + result.PlacementGroup = PlacementGroupFromSchema(respBody.PlacementGroup) if respBody.Action != nil { result.Action = ActionFromSchema(*respBody.Action) } @@ -210,6 +180,11 @@ type PlacementGroupUpdateOpts struct { // Update updates a PlacementGroup. func (c *PlacementGroupClient) Update(ctx context.Context, placementGroup *PlacementGroup, opts PlacementGroupUpdateOpts) (*PlacementGroup, *Response, error) { + const opPath = "/placement_groups/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, placementGroup.ID) + reqBody := schema.PlacementGroupUpdateRequest{} if opts.Name != "" { reqBody.Name = &opts.Name @@ -217,19 +192,8 @@ func (c *PlacementGroupClient) Update(ctx context.Context, placementGroup *Place if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/placement_groups/%d", placementGroup.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.PlacementGroupUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.PlacementGroupUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } @@ -239,9 +203,10 @@ func (c *PlacementGroupClient) Update(ctx context.Context, placementGroup *Place // Delete deletes a PlacementGroup. func (c *PlacementGroupClient) Delete(ctx context.Context, placementGroup *PlacementGroup) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/placement_groups/%d", placementGroup.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/placement_groups/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, placementGroup.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/pricing.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/pricing.go similarity index 88% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/pricing.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/pricing.go index e8ca92d59b334..b8721c1249aa7 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/pricing.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/pricing.go @@ -3,12 +3,14 @@ package hcloud import ( "context" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Pricing specifies pricing information for various resources. type Pricing struct { - Image ImagePricing + Image ImagePricing + // Deprecated: [Pricing.FloatingIP] is deprecated, use [Pricing.FloatingIPs] instead. FloatingIP FloatingIPPricing FloatingIPs []FloatingIPTypePricing PrimaryIPs []PrimaryIPPricing @@ -135,15 +137,15 @@ type PricingClient struct { // Get retrieves pricing information. func (c *PricingClient) Get(ctx context.Context) (Pricing, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", "/pricing", nil) - if err != nil { - return Pricing{}, nil, err - } + const opPath = "/pricing" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.PricingGetResponse - resp, err := c.client.Do(req, &body) + reqPath := opPath + + respBody, resp, err := getRequest[schema.PricingGetResponse](ctx, c.client, reqPath) if err != nil { - return Pricing{}, nil, err + return Pricing{}, resp, err } - return PricingFromSchema(body.Pricing), resp, nil + + return PricingFromSchema(respBody.Pricing), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/primary_ip.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/primary_ip.go new file mode 100644 index 0000000000000..027e8c39019e4 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/primary_ip.go @@ -0,0 +1,359 @@ +package hcloud + +import ( + "context" + "fmt" + "net" + "net/url" + "time" + + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" +) + +// PrimaryIP defines a Primary IP. +type PrimaryIP struct { + ID int64 + IP net.IP + Network *net.IPNet + Labels map[string]string + Name string + Type PrimaryIPType + Protection PrimaryIPProtection + DNSPtr map[string]string + AssigneeID int64 + AssigneeType string + AutoDelete bool + Blocked bool + Created time.Time + Datacenter *Datacenter +} + +// PrimaryIPProtection represents the protection level of a Primary IP. +type PrimaryIPProtection struct { + Delete bool +} + +// PrimaryIPDNSPTR contains reverse DNS information for a +// IPv4 or IPv6 Primary IP. +type PrimaryIPDNSPTR struct { + DNSPtr string + IP string +} + +// changeDNSPtr changes or resets the reverse DNS pointer for a IP address. +// Pass a nil ptr to reset the reverse DNS pointer to its default value. +func (p *PrimaryIP) changeDNSPtr(ctx context.Context, client *Client, ip net.IP, ptr *string) (*Action, *Response, error) { + const opPath = "/primary_ips/%d/actions/change_dns_ptr" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, p.ID) + + reqBody := schema.PrimaryIPActionChangeDNSPtrRequest{ + IP: ip.String(), + DNSPtr: ptr, + } + + respBody, resp, err := postRequest[schema.PrimaryIPActionChangeDNSPtrResponse](ctx, client, reqPath, reqBody) + if err != nil { + return nil, resp, err + } + + return ActionFromSchema(respBody.Action), resp, nil +} + +// GetDNSPtrForIP searches for the dns assigned to the given IP address. +// It returns an error if there is no dns set for the given IP address. +func (p *PrimaryIP) GetDNSPtrForIP(ip net.IP) (string, error) { + dns, ok := p.DNSPtr[ip.String()] + if !ok { + return "", DNSNotFoundError{ip} + } + + return dns, nil +} + +// PrimaryIPType represents the type of Primary IP. +type PrimaryIPType string + +// PrimaryIPType Primary IP types. +const ( + PrimaryIPTypeIPv4 PrimaryIPType = "ipv4" + PrimaryIPTypeIPv6 PrimaryIPType = "ipv6" +) + +// PrimaryIPCreateOpts defines the request to +// create a Primary IP. +type PrimaryIPCreateOpts struct { + AssigneeID *int64 + AssigneeType string + AutoDelete *bool + Datacenter string + Labels map[string]string + Name string + Type PrimaryIPType +} + +// PrimaryIPCreateResult defines the response +// when creating a Primary IP. +type PrimaryIPCreateResult struct { + PrimaryIP *PrimaryIP + Action *Action +} + +// PrimaryIPUpdateOpts defines the request to +// update a Primary IP. +type PrimaryIPUpdateOpts struct { + AutoDelete *bool + Labels *map[string]string + Name string +} + +// PrimaryIPAssignOpts defines the request to +// assign a Primary IP to an assignee (usually a server). +type PrimaryIPAssignOpts struct { + ID int64 + AssigneeID int64 + AssigneeType string +} + +// Deprecated: Please use [schema.PrimaryIPActionAssignResponse] instead. +type PrimaryIPAssignResult = schema.PrimaryIPActionAssignResponse + +// PrimaryIPChangeDNSPtrOpts defines the request to +// change a DNS PTR entry from a Primary IP. +type PrimaryIPChangeDNSPtrOpts struct { + ID int64 + DNSPtr string + IP string +} + +// Deprecated: Please use [schema.PrimaryIPChangeDNSPtrResponse] instead. +type PrimaryIPChangeDNSPtrResult = schema.PrimaryIPActionChangeDNSPtrResponse + +// PrimaryIPChangeProtectionOpts defines the request to +// change protection configuration of a Primary IP. +type PrimaryIPChangeProtectionOpts struct { + ID int64 + Delete bool +} + +// Deprecated: Please use [schema.PrimaryIPActionChangeProtectionResponse] instead. +type PrimaryIPChangeProtectionResult = schema.PrimaryIPActionChangeProtectionResponse + +// PrimaryIPClient is a client for the Primary IP API. +type PrimaryIPClient struct { + client *Client + Action *ResourceActionClient +} + +// GetByID retrieves a Primary IP by its ID. If the Primary IP does not exist, nil is returned. +func (c *PrimaryIPClient) GetByID(ctx context.Context, id int64) (*PrimaryIP, *Response, error) { + const opPath = "/primary_ips/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) + + respBody, resp, err := getRequest[schema.PrimaryIPGetResponse](ctx, c.client, reqPath) + if err != nil { + if IsError(err, ErrorCodeNotFound) { + return nil, resp, nil + } + return nil, resp, err + } + + return PrimaryIPFromSchema(respBody.PrimaryIP), resp, nil +} + +// GetByIP retrieves a Primary IP by its IP Address. If the Primary IP does not exist, nil is returned. +func (c *PrimaryIPClient) GetByIP(ctx context.Context, ip string) (*PrimaryIP, *Response, error) { + if ip == "" { + return nil, nil, nil + } + return firstBy(func() ([]*PrimaryIP, *Response, error) { + return c.List(ctx, PrimaryIPListOpts{IP: ip}) + }) +} + +// GetByName retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. +func (c *PrimaryIPClient) GetByName(ctx context.Context, name string) (*PrimaryIP, *Response, error) { + return firstByName(name, func() ([]*PrimaryIP, *Response, error) { + return c.List(ctx, PrimaryIPListOpts{Name: name}) + }) +} + +// Get retrieves a Primary IP by its ID if the input can be parsed as an integer, otherwise it +// retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. +func (c *PrimaryIPClient) Get(ctx context.Context, idOrName string) (*PrimaryIP, *Response, error) { + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) +} + +// PrimaryIPListOpts specifies options for listing Primary IPs. +type PrimaryIPListOpts struct { + ListOpts + Name string + IP string + Sort []string +} + +func (l PrimaryIPListOpts) values() url.Values { + vals := l.ListOpts.Values() + if l.Name != "" { + vals.Add("name", l.Name) + } + if l.IP != "" { + vals.Add("ip", l.IP) + } + for _, sort := range l.Sort { + vals.Add("sort", sort) + } + return vals +} + +// List returns a list of Primary IPs for a specific page. +// +// Please note that filters specified in opts are not taken into account +// when their value corresponds to their zero value or when they are empty. +func (c *PrimaryIPClient) List(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, *Response, error) { + const opPath = "/primary_ips?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.PrimaryIPListResponse](ctx, c.client, reqPath) + if err != nil { + return nil, resp, err + } + + return allFromSchemaFunc(respBody.PrimaryIPs, PrimaryIPFromSchema), resp, nil +} + +// All returns all Primary IPs. +func (c *PrimaryIPClient) All(ctx context.Context) ([]*PrimaryIP, error) { + return c.AllWithOpts(ctx, PrimaryIPListOpts{ListOpts: ListOpts{PerPage: 50}}) +} + +// AllWithOpts returns all Primary IPs for the given options. +func (c *PrimaryIPClient) AllWithOpts(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, error) { + return iterPages(func(page int) ([]*PrimaryIP, *Response, error) { + opts.Page = page + return c.List(ctx, opts) + }) +} + +// Create creates a Primary IP. +func (c *PrimaryIPClient) Create(ctx context.Context, opts PrimaryIPCreateOpts) (*PrimaryIPCreateResult, *Response, error) { + const opPath = "/primary_ips" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := &PrimaryIPCreateResult{} + + reqPath := opPath + + reqBody := SchemaFromPrimaryIPCreateOpts(opts) + + respBody, resp, err := postRequest[schema.PrimaryIPCreateResponse](ctx, c.client, reqPath, reqBody) + if err != nil { + return result, resp, err + } + + result.PrimaryIP = PrimaryIPFromSchema(respBody.PrimaryIP) + if respBody.Action != nil { + result.Action = ActionFromSchema(*respBody.Action) + } + + return result, resp, nil +} + +// Delete deletes a Primary IP. +func (c *PrimaryIPClient) Delete(ctx context.Context, primaryIP *PrimaryIP) (*Response, error) { + const opPath = "/primary_ips/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, primaryIP.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) +} + +// Update updates a Primary IP. +func (c *PrimaryIPClient) Update(ctx context.Context, primaryIP *PrimaryIP, opts PrimaryIPUpdateOpts) (*PrimaryIP, *Response, error) { + const opPath = "/primary_ips/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, primaryIP.ID) + + reqBody := SchemaFromPrimaryIPUpdateOpts(opts) + + respBody, resp, err := putRequest[schema.PrimaryIPUpdateResponse](ctx, c.client, reqPath, reqBody) + if err != nil { + return nil, resp, err + } + + return PrimaryIPFromSchema(respBody.PrimaryIP), resp, nil +} + +// Assign a Primary IP to a resource. +func (c *PrimaryIPClient) Assign(ctx context.Context, opts PrimaryIPAssignOpts) (*Action, *Response, error) { + const opPath = "/primary_ips/%d/actions/assign" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.ID) + + reqBody := SchemaFromPrimaryIPAssignOpts(opts) + + respBody, resp, err := postRequest[schema.PrimaryIPActionAssignResponse](ctx, c.client, reqPath, reqBody) + if err != nil { + return nil, resp, err + } + + return ActionFromSchema(respBody.Action), resp, nil +} + +// Unassign a Primary IP from a resource. +func (c *PrimaryIPClient) Unassign(ctx context.Context, id int64) (*Action, *Response, error) { + const opPath = "/primary_ips/%d/actions/unassign" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) + + respBody, resp, err := postRequest[schema.PrimaryIPActionUnassignResponse](ctx, c.client, reqPath, nil) + if err != nil { + return nil, resp, err + } + + return ActionFromSchema(respBody.Action), resp, nil +} + +// ChangeDNSPtr Change the reverse DNS from a Primary IP. +func (c *PrimaryIPClient) ChangeDNSPtr(ctx context.Context, opts PrimaryIPChangeDNSPtrOpts) (*Action, *Response, error) { + const opPath = "/primary_ips/%d/actions/change_dns_ptr" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.ID) + + reqBody := SchemaFromPrimaryIPChangeDNSPtrOpts(opts) + + respBody, resp, err := postRequest[schema.PrimaryIPActionChangeDNSPtrResponse](ctx, c.client, reqPath, reqBody) + if err != nil { + return nil, resp, err + } + + return ActionFromSchema(respBody.Action), resp, nil +} + +// ChangeProtection Changes the protection configuration of a Primary IP. +func (c *PrimaryIPClient) ChangeProtection(ctx context.Context, opts PrimaryIPChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/primary_ips/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.ID) + + reqBody := SchemaFromPrimaryIPChangeProtectionOpts(opts) + + respBody, resp, err := postRequest[schema.PrimaryIPActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) + if err != nil { + return nil, resp, err + } + + return ActionFromSchema(respBody.Action), resp, nil +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/rdns.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/rdns.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/rdns.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/rdns.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/resource.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/resource.go similarity index 89% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/resource.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/resource.go index 8a734dfd69daf..a74b2cf7aefc4 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/resource.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/resource.go @@ -2,6 +2,6 @@ package hcloud // Resource defines the schema of a resource. type Resource struct { - ID int + ID int64 Type string } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema.go new file mode 100644 index 0000000000000..df2097f1c796e --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema.go @@ -0,0 +1,390 @@ +package hcloud + +import ( + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" +) + +// This file provides converter functions to convert models in the +// schema package to models in the hcloud package and vice versa. + +var c converter + +// ActionFromSchema converts a schema.Action to an Action. +func ActionFromSchema(s schema.Action) *Action { + return c.ActionFromSchema(s) +} + +// SchemaFromAction converts an Action to a schema.Action. +func SchemaFromAction(a *Action) schema.Action { + return c.SchemaFromAction(a) +} + +// ActionsFromSchema converts a slice of schema.Action to a slice of Action. +func ActionsFromSchema(s []schema.Action) []*Action { + return c.ActionsFromSchema(s) +} + +// SchemaFromActions converts a slice of Action to a slice of schema.Action. +func SchemaFromActions(a []*Action) []schema.Action { + return c.SchemaFromActions(a) +} + +// FloatingIPFromSchema converts a schema.FloatingIP to a FloatingIP. +func FloatingIPFromSchema(s schema.FloatingIP) *FloatingIP { + return c.FloatingIPFromSchema(s) +} + +// SchemaFromFloatingIP converts a FloatingIP to a schema.FloatingIP. +func SchemaFromFloatingIP(f *FloatingIP) schema.FloatingIP { + return c.SchemaFromFloatingIP(f) +} + +// PrimaryIPFromSchema converts a schema.PrimaryIP to a PrimaryIP. +func PrimaryIPFromSchema(s schema.PrimaryIP) *PrimaryIP { + return c.PrimaryIPFromSchema(s) +} + +// SchemaFromPrimaryIP converts a PrimaryIP to a schema.PrimaryIP. +func SchemaFromPrimaryIP(p *PrimaryIP) schema.PrimaryIP { + return c.SchemaFromPrimaryIP(p) +} + +func SchemaFromPrimaryIPCreateOpts(o PrimaryIPCreateOpts) schema.PrimaryIPCreateRequest { + return c.SchemaFromPrimaryIPCreateOpts(o) +} + +func SchemaFromPrimaryIPUpdateOpts(o PrimaryIPUpdateOpts) schema.PrimaryIPUpdateRequest { + return c.SchemaFromPrimaryIPUpdateOpts(o) +} + +func SchemaFromPrimaryIPChangeDNSPtrOpts(o PrimaryIPChangeDNSPtrOpts) schema.PrimaryIPActionChangeDNSPtrRequest { + return c.SchemaFromPrimaryIPChangeDNSPtrOpts(o) +} + +func SchemaFromPrimaryIPChangeProtectionOpts(o PrimaryIPChangeProtectionOpts) schema.PrimaryIPActionChangeProtectionRequest { + return c.SchemaFromPrimaryIPChangeProtectionOpts(o) +} + +func SchemaFromPrimaryIPAssignOpts(o PrimaryIPAssignOpts) schema.PrimaryIPActionAssignRequest { + return c.SchemaFromPrimaryIPAssignOpts(o) +} + +// ISOFromSchema converts a schema.ISO to an ISO. +func ISOFromSchema(s schema.ISO) *ISO { + return c.ISOFromSchema(s) +} + +// SchemaFromISO converts an ISO to a schema.ISO. +func SchemaFromISO(i *ISO) schema.ISO { + return c.SchemaFromISO(i) +} + +// LocationFromSchema converts a schema.Location to a Location. +func LocationFromSchema(s schema.Location) *Location { + return c.LocationFromSchema(s) +} + +// SchemaFromLocation converts a Location to a schema.Location. +func SchemaFromLocation(l *Location) schema.Location { + return c.SchemaFromLocation(l) +} + +// DatacenterFromSchema converts a schema.Datacenter to a Datacenter. +func DatacenterFromSchema(s schema.Datacenter) *Datacenter { + return c.DatacenterFromSchema(s) +} + +// SchemaFromDatacenter converts a Datacenter to a schema.Datacenter. +func SchemaFromDatacenter(d *Datacenter) schema.Datacenter { + return c.SchemaFromDatacenter(d) +} + +// ServerFromSchema converts a schema.Server to a Server. +func ServerFromSchema(s schema.Server) *Server { + return c.ServerFromSchema(s) +} + +// SchemaFromServer converts a Server to a schema.Server. +func SchemaFromServer(s *Server) schema.Server { + return c.SchemaFromServer(s) +} + +// ServerPublicNetFromSchema converts a schema.ServerPublicNet to a ServerPublicNet. +func ServerPublicNetFromSchema(s schema.ServerPublicNet) ServerPublicNet { + return c.ServerPublicNetFromSchema(s) +} + +// SchemaFromServerPublicNet converts a ServerPublicNet to a schema.ServerPublicNet. +func SchemaFromServerPublicNet(s ServerPublicNet) schema.ServerPublicNet { + return c.SchemaFromServerPublicNet(s) +} + +// ServerPublicNetIPv4FromSchema converts a schema.ServerPublicNetIPv4 to +// a ServerPublicNetIPv4. +func ServerPublicNetIPv4FromSchema(s schema.ServerPublicNetIPv4) ServerPublicNetIPv4 { + return c.ServerPublicNetIPv4FromSchema(s) +} + +// SchemaFromServerPublicNetIPv4 converts a ServerPublicNetIPv4 to +// a schema.ServerPublicNetIPv4. +func SchemaFromServerPublicNetIPv4(s ServerPublicNetIPv4) schema.ServerPublicNetIPv4 { + return c.SchemaFromServerPublicNetIPv4(s) +} + +// ServerPublicNetIPv6FromSchema converts a schema.ServerPublicNetIPv6 to +// a ServerPublicNetIPv6. +func ServerPublicNetIPv6FromSchema(s schema.ServerPublicNetIPv6) ServerPublicNetIPv6 { + return c.ServerPublicNetIPv6FromSchema(s) +} + +// SchemaFromServerPublicNetIPv6 converts a ServerPublicNetIPv6 to +// a schema.ServerPublicNetIPv6. +func SchemaFromServerPublicNetIPv6(s ServerPublicNetIPv6) schema.ServerPublicNetIPv6 { + return c.SchemaFromServerPublicNetIPv6(s) +} + +// ServerPrivateNetFromSchema converts a schema.ServerPrivateNet to a ServerPrivateNet. +func ServerPrivateNetFromSchema(s schema.ServerPrivateNet) ServerPrivateNet { + return c.ServerPrivateNetFromSchema(s) +} + +// SchemaFromServerPrivateNet converts a ServerPrivateNet to a schema.ServerPrivateNet. +func SchemaFromServerPrivateNet(s ServerPrivateNet) schema.ServerPrivateNet { + return c.SchemaFromServerPrivateNet(s) +} + +// ServerTypeFromSchema converts a schema.ServerType to a ServerType. +func ServerTypeFromSchema(s schema.ServerType) *ServerType { + return c.ServerTypeFromSchema(s) +} + +// SchemaFromServerType converts a ServerType to a schema.ServerType. +func SchemaFromServerType(s *ServerType) schema.ServerType { + return c.SchemaFromServerType(s) +} + +// SSHKeyFromSchema converts a schema.SSHKey to a SSHKey. +func SSHKeyFromSchema(s schema.SSHKey) *SSHKey { + return c.SSHKeyFromSchema(s) +} + +// SchemaFromSSHKey converts a SSHKey to a schema.SSHKey. +func SchemaFromSSHKey(s *SSHKey) schema.SSHKey { + return c.SchemaFromSSHKey(s) +} + +// ImageFromSchema converts a schema.Image to an Image. +func ImageFromSchema(s schema.Image) *Image { + return c.ImageFromSchema(s) +} + +// SchemaFromImage converts an Image to a schema.Image. +func SchemaFromImage(i *Image) schema.Image { + return c.SchemaFromImage(i) +} + +// VolumeFromSchema converts a schema.Volume to a Volume. +func VolumeFromSchema(s schema.Volume) *Volume { + return c.VolumeFromSchema(s) +} + +// SchemaFromVolume converts a Volume to a schema.Volume. +func SchemaFromVolume(v *Volume) schema.Volume { + return c.SchemaFromVolume(v) +} + +// NetworkFromSchema converts a schema.Network to a Network. +func NetworkFromSchema(s schema.Network) *Network { + return c.NetworkFromSchema(s) +} + +// SchemaFromNetwork converts a Network to a schema.Network. +func SchemaFromNetwork(n *Network) schema.Network { + return c.SchemaFromNetwork(n) +} + +// NetworkSubnetFromSchema converts a schema.NetworkSubnet to a NetworkSubnet. +func NetworkSubnetFromSchema(s schema.NetworkSubnet) NetworkSubnet { + return c.NetworkSubnetFromSchema(s) +} + +// SchemaFromNetworkSubnet converts a NetworkSubnet to a schema.NetworkSubnet. +func SchemaFromNetworkSubnet(n NetworkSubnet) schema.NetworkSubnet { + return c.SchemaFromNetworkSubnet(n) +} + +// NetworkRouteFromSchema converts a schema.NetworkRoute to a NetworkRoute. +func NetworkRouteFromSchema(s schema.NetworkRoute) NetworkRoute { + return c.NetworkRouteFromSchema(s) +} + +// SchemaFromNetworkRoute converts a NetworkRoute to a schema.NetworkRoute. +func SchemaFromNetworkRoute(n NetworkRoute) schema.NetworkRoute { + return c.SchemaFromNetworkRoute(n) +} + +// LoadBalancerTypeFromSchema converts a schema.LoadBalancerType to a LoadBalancerType. +func LoadBalancerTypeFromSchema(s schema.LoadBalancerType) *LoadBalancerType { + return c.LoadBalancerTypeFromSchema(s) +} + +// SchemaFromLoadBalancerType converts a LoadBalancerType to a schema.LoadBalancerType. +func SchemaFromLoadBalancerType(l *LoadBalancerType) schema.LoadBalancerType { + return c.SchemaFromLoadBalancerType(l) +} + +// LoadBalancerFromSchema converts a schema.LoadBalancer to a LoadBalancer. +func LoadBalancerFromSchema(s schema.LoadBalancer) *LoadBalancer { + return c.LoadBalancerFromSchema(s) +} + +// SchemaFromLoadBalancer converts a LoadBalancer to a schema.LoadBalancer. +func SchemaFromLoadBalancer(l *LoadBalancer) schema.LoadBalancer { + return c.SchemaFromLoadBalancer(l) +} + +// LoadBalancerServiceFromSchema converts a schema.LoadBalancerService to a LoadBalancerService. +func LoadBalancerServiceFromSchema(s schema.LoadBalancerService) LoadBalancerService { + return c.LoadBalancerServiceFromSchema(s) +} + +// SchemaFromLoadBalancerService converts a LoadBalancerService to a schema.LoadBalancerService. +func SchemaFromLoadBalancerService(l LoadBalancerService) schema.LoadBalancerService { + return c.SchemaFromLoadBalancerService(l) +} + +// LoadBalancerServiceHealthCheckFromSchema converts a schema.LoadBalancerServiceHealthCheck to a LoadBalancerServiceHealthCheck. +func LoadBalancerServiceHealthCheckFromSchema(s *schema.LoadBalancerServiceHealthCheck) LoadBalancerServiceHealthCheck { + return c.LoadBalancerServiceHealthCheckFromSchema(s) +} + +// SchemaFromLoadBalancerServiceHealthCheck converts a LoadBalancerServiceHealthCheck to a schema.LoadBalancerServiceHealthCheck. +func SchemaFromLoadBalancerServiceHealthCheck(l LoadBalancerServiceHealthCheck) *schema.LoadBalancerServiceHealthCheck { + return c.SchemaFromLoadBalancerServiceHealthCheck(l) +} + +// LoadBalancerTargetFromSchema converts a schema.LoadBalancerTarget to a LoadBalancerTarget. +func LoadBalancerTargetFromSchema(s schema.LoadBalancerTarget) LoadBalancerTarget { + return c.LoadBalancerTargetFromSchema(s) +} + +// SchemaFromLoadBalancerTarget converts a LoadBalancerTarget to a schema.LoadBalancerTarget. +func SchemaFromLoadBalancerTarget(l LoadBalancerTarget) schema.LoadBalancerTarget { + return c.SchemaFromLoadBalancerTarget(l) +} + +// LoadBalancerTargetHealthStatusFromSchema converts a schema.LoadBalancerTarget to a LoadBalancerTarget. +func LoadBalancerTargetHealthStatusFromSchema(s schema.LoadBalancerTargetHealthStatus) LoadBalancerTargetHealthStatus { + return c.LoadBalancerTargetHealthStatusFromSchema(s) +} + +// SchemaFromLoadBalancerTargetHealthStatus converts a LoadBalancerTarget to a schema.LoadBalancerTarget. +func SchemaFromLoadBalancerTargetHealthStatus(l LoadBalancerTargetHealthStatus) schema.LoadBalancerTargetHealthStatus { + return c.SchemaFromLoadBalancerTargetHealthStatus(l) +} + +// CertificateFromSchema converts a schema.Certificate to a Certificate. +func CertificateFromSchema(s schema.Certificate) *Certificate { + return c.CertificateFromSchema(s) +} + +// SchemaFromCertificate converts a Certificate to a schema.Certificate. +func SchemaFromCertificate(ct *Certificate) schema.Certificate { + return c.SchemaFromCertificate(ct) +} + +// PaginationFromSchema converts a schema.MetaPagination to a Pagination. +func PaginationFromSchema(s schema.MetaPagination) Pagination { + return c.PaginationFromSchema(s) +} + +// SchemaFromPagination converts a Pagination to a schema.MetaPagination. +func SchemaFromPagination(p Pagination) schema.MetaPagination { + return c.SchemaFromPagination(p) +} + +// ErrorFromSchema converts a schema.Error to an Error. +func ErrorFromSchema(s schema.Error) Error { + return c.ErrorFromSchema(s) +} + +// SchemaFromError converts an Error to a schema.Error. +func SchemaFromError(e Error) schema.Error { + return c.SchemaFromError(e) +} + +// PricingFromSchema converts a schema.Pricing to a Pricing. +func PricingFromSchema(s schema.Pricing) Pricing { + return c.PricingFromSchema(s) +} + +// SchemaFromPricing converts a Pricing to a schema.Pricing. +func SchemaFromPricing(p Pricing) schema.Pricing { + return c.SchemaFromPricing(p) +} + +// FirewallFromSchema converts a schema.Firewall to a Firewall. +func FirewallFromSchema(s schema.Firewall) *Firewall { + return c.FirewallFromSchema(s) +} + +// SchemaFromFirewall converts a Firewall to a schema.Firewall. +func SchemaFromFirewall(f *Firewall) schema.Firewall { + return c.SchemaFromFirewall(f) +} + +// PlacementGroupFromSchema converts a schema.PlacementGroup to a PlacementGroup. +func PlacementGroupFromSchema(s schema.PlacementGroup) *PlacementGroup { + return c.PlacementGroupFromSchema(s) +} + +// SchemaFromPlacementGroup converts a PlacementGroup to a schema.PlacementGroup. +func SchemaFromPlacementGroup(p *PlacementGroup) schema.PlacementGroup { + return c.SchemaFromPlacementGroup(p) +} + +// DeprecationFromSchema converts a [schema.DeprecationInfo] to a [DeprecationInfo]. +func DeprecationFromSchema(s *schema.DeprecationInfo) *DeprecationInfo { + return c.DeprecationFromSchema(s) +} + +// SchemaFromDeprecation converts a [DeprecationInfo] to a [schema.DeprecationInfo]. +func SchemaFromDeprecation(d *DeprecationInfo) *schema.DeprecationInfo { + return c.SchemaFromDeprecation(d) +} + +func placementGroupCreateOptsToSchema(opts PlacementGroupCreateOpts) schema.PlacementGroupCreateRequest { + return c.SchemaFromPlacementGroupCreateOpts(opts) +} + +func loadBalancerCreateOptsToSchema(opts LoadBalancerCreateOpts) schema.LoadBalancerCreateRequest { + return c.SchemaFromLoadBalancerCreateOpts(opts) +} + +func loadBalancerAddServiceOptsToSchema(opts LoadBalancerAddServiceOpts) schema.LoadBalancerActionAddServiceRequest { + return c.SchemaFromLoadBalancerAddServiceOpts(opts) +} + +func loadBalancerUpdateServiceOptsToSchema(opts LoadBalancerUpdateServiceOpts) schema.LoadBalancerActionUpdateServiceRequest { + return c.SchemaFromLoadBalancerUpdateServiceOpts(opts) +} + +func firewallCreateOptsToSchema(opts FirewallCreateOpts) schema.FirewallCreateRequest { + return c.SchemaFromFirewallCreateOpts(opts) +} + +func firewallSetRulesOptsToSchema(opts FirewallSetRulesOpts) schema.FirewallActionSetRulesRequest { + return c.SchemaFromFirewallSetRulesOpts(opts) +} + +func firewallResourceToSchema(resource FirewallResource) schema.FirewallResource { + return c.SchemaFromFirewallResource(resource) +} + +func serverMetricsFromSchema(s *schema.ServerGetMetricsResponse) (*ServerMetrics, error) { + return c.ServerMetricsFromSchema(s) +} + +func loadBalancerMetricsFromSchema(s *schema.LoadBalancerGetMetricsResponse) (*LoadBalancerMetrics, error) { + return c.LoadBalancerMetricsFromSchema(s) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/README.md b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/README.md new file mode 100644 index 0000000000000..9203e3f6feb7e --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/README.md @@ -0,0 +1,6 @@ +# Schema + +The [`schema`](./) package holds API schemas for the `hcloud-go` library. + +> [!CAUTION] +> Breaking changes may occur without notice. Do not use in production! diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/action.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/action.go similarity index 93% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/action.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/action.go index df4d7cf71b8f7..49ac96a229531 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/action.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/action.go @@ -4,7 +4,7 @@ import "time" // Action defines the schema of an action. type Action struct { - ID int `json:"id"` + ID int64 `json:"id"` Status string `json:"status"` Command string `json:"command"` Progress int `json:"progress"` @@ -16,7 +16,7 @@ type Action struct { // ActionResourceReference defines the schema of an action resource reference. type ActionResourceReference struct { - ID int `json:"id"` + ID int64 `json:"id"` Type string `json:"type"` } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/certificate.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/certificate.go similarity index 97% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/certificate.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/certificate.go index a81b807a29397..eb7b03ce2138b 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/certificate.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/certificate.go @@ -4,7 +4,7 @@ import "time" // CertificateUsedByRef defines the schema of a resource using a certificate. type CertificateUsedByRef struct { - ID int `json:"id"` + ID int64 `json:"id"` Type string `json:"type"` } @@ -16,7 +16,7 @@ type CertificateStatusRef struct { // Certificate defines the schema of an certificate. type Certificate struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Labels map[string]string `json:"labels"` Type string `json:"type"` diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/datacenter.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/datacenter.go new file mode 100644 index 0000000000000..54590d2a2a541 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/datacenter.go @@ -0,0 +1,27 @@ +package schema + +// Datacenter defines the schema of a datacenter. +type Datacenter struct { + ID int64 `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Location Location `json:"location"` + ServerTypes DatacenterServerTypes `json:"server_types"` +} + +// DatacenterServerTypes defines the schema of the server types available in a datacenter. +type DatacenterServerTypes struct { + Supported []int64 `json:"supported"` + AvailableForMigration []int64 `json:"available_for_migration"` + Available []int64 `json:"available"` +} + +// DatacenterGetResponse defines the schema of the response when retrieving a single datacenter. +type DatacenterGetResponse struct { + Datacenter Datacenter `json:"datacenter"` +} + +// DatacenterListResponse defines the schema of the response when listing datacenters. +type DatacenterListResponse struct { + Datacenters []Datacenter `json:"datacenters"` +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/deprecation.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/deprecation.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/deprecation.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/deprecation.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/doc.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/doc.go new file mode 100644 index 0000000000000..057aef057f050 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/doc.go @@ -0,0 +1,4 @@ +// The schema package holds API schemas for the `hcloud-go` library. + +// Breaking changes may occur without notice. Do not use in production! +package schema diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/error.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/error.go similarity index 68% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/error.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/error.go index 86a5455ea9239..f1066bdee67e3 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/error.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/error.go @@ -7,7 +7,7 @@ type Error struct { Code string `json:"code"` Message string `json:"message"` DetailsRaw json.RawMessage `json:"details"` - Details interface{} + Details any `json:"-"` } // UnmarshalJSON overrides default json unmarshalling. @@ -24,6 +24,13 @@ func (e *Error) UnmarshalJSON(data []byte) (err error) { } alias.Details = details } + if e.Code == "deprecated_api_endpoint" && len(e.DetailsRaw) > 0 { + details := ErrorDetailsDeprecatedAPIEndpoint{} + if err = json.Unmarshal(e.DetailsRaw, &details); err != nil { + return + } + alias.Details = details + } return } @@ -40,3 +47,9 @@ type ErrorDetailsInvalidInput struct { Messages []string `json:"messages"` } `json:"fields"` } + +// ErrorDetailsDeprecatedAPIEndpoint defines the schema of the Details field +// of an error with code 'deprecated_api_endpoint'. +type ErrorDetailsDeprecatedAPIEndpoint struct { + Announcement string `json:"announcement"` +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/firewall.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/firewall.go similarity index 98% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/firewall.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/firewall.go index bf5afc7c04bd1..d393f1e0e0e79 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/firewall.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/firewall.go @@ -4,7 +4,7 @@ import "time" // Firewall defines the schema of a Firewall. type Firewall struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Labels map[string]string `json:"labels"` Created time.Time `json:"created"` @@ -64,7 +64,7 @@ type FirewallResourceLabelSelector struct { // FirewallResourceServer defines the schema of a Server to apply a Firewall on. type FirewallResourceServer struct { - ID int `json:"id"` + ID int64 `json:"id"` } // FirewallCreateResponse defines the schema of the response when creating a Firewall. diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/floating_ip.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/floating_ip.go similarity index 95% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/floating_ip.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/floating_ip.go index 37295dad9c1ce..6256b0d96f8dd 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/floating_ip.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/floating_ip.go @@ -4,12 +4,12 @@ import "time" // FloatingIP defines the schema of a Floating IP. type FloatingIP struct { - ID int `json:"id"` + ID int64 `json:"id"` Description *string `json:"description"` Created time.Time `json:"created"` IP string `json:"ip"` Type string `json:"type"` - Server *int `json:"server"` + Server *int64 `json:"server"` DNSPtr []FloatingIPDNSPtr `json:"dns_ptr"` HomeLocation Location `json:"home_location"` Blocked bool `json:"blocked"` @@ -59,7 +59,7 @@ type FloatingIPListResponse struct { type FloatingIPCreateRequest struct { Type string `json:"type"` HomeLocation *string `json:"home_location,omitempty"` - Server *int `json:"server,omitempty"` + Server *int64 `json:"server,omitempty"` Description *string `json:"description,omitempty"` Labels *map[string]string `json:"labels,omitempty"` Name *string `json:"name,omitempty"` @@ -75,7 +75,7 @@ type FloatingIPCreateResponse struct { // FloatingIPActionAssignRequest defines the schema of the request to // create an assign Floating IP action. type FloatingIPActionAssignRequest struct { - Server int `json:"server"` + Server int64 `json:"server"` } // FloatingIPActionAssignResponse defines the schema of the response when diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/id_or_name.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/id_or_name.go new file mode 100644 index 0000000000000..75e1169bd47ac --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/id_or_name.go @@ -0,0 +1,68 @@ +package schema + +import ( + "bytes" + "encoding/json" + "reflect" + "strconv" +) + +// IDOrName can be used in API requests where either a resource id or name can be +// specified. +type IDOrName struct { + ID int64 + Name string +} + +var _ json.Unmarshaler = (*IDOrName)(nil) +var _ json.Marshaler = (*IDOrName)(nil) + +func (o IDOrName) MarshalJSON() ([]byte, error) { + if o.ID != 0 { + return json.Marshal(o.ID) + } + if o.Name != "" { + return json.Marshal(o.Name) + } + + // We want to preserve the behavior of an empty interface{} to prevent breaking + // changes (marshaled to null when empty). + return json.Marshal(nil) +} + +func (o *IDOrName) UnmarshalJSON(data []byte) error { + d := json.NewDecoder(bytes.NewBuffer(data)) + // This ensures we won't lose precision on large IDs, see json.Number below + d.UseNumber() + + var v any + if err := d.Decode(&v); err != nil { + return err + } + + switch typed := v.(type) { + case string: + id, err := strconv.ParseInt(typed, 10, 64) + if err == nil { + o.ID = id + } else if typed != "" { + o.Name = typed + } + case json.Number: + id, err := typed.Int64() + if err != nil { + return &json.UnmarshalTypeError{ + Value: string(data), + Type: reflect.TypeOf(*o), + } + } + o.ID = id + default: + return &json.UnmarshalTypeError{ + Value: string(data), + Type: reflect.TypeOf(*o), + } + } + + return nil +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/image.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/image.go similarity index 88% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/image.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/image.go index 76775b131c429..eacc20f896212 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/image.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/image.go @@ -4,23 +4,23 @@ import "time" // Image defines the schema of an image. type Image struct { - ID int `json:"id"` + ID int64 `json:"id"` Status string `json:"status"` Type string `json:"type"` Name *string `json:"name"` Description string `json:"description"` ImageSize *float32 `json:"image_size"` DiskSize float32 `json:"disk_size"` - Created time.Time `json:"created"` + Created *time.Time `json:"created"` CreatedFrom *ImageCreatedFrom `json:"created_from"` - BoundTo *int `json:"bound_to"` + BoundTo *int64 `json:"bound_to"` OSFlavor string `json:"os_flavor"` OSVersion *string `json:"os_version"` Architecture string `json:"architecture"` RapidDeploy bool `json:"rapid_deploy"` Protection ImageProtection `json:"protection"` - Deprecated time.Time `json:"deprecated"` - Deleted time.Time `json:"deleted"` + Deprecated *time.Time `json:"deprecated"` + Deleted *time.Time `json:"deleted"` Labels map[string]string `json:"labels"` } @@ -31,7 +31,7 @@ type ImageProtection struct { // ImageCreatedFrom defines the schema of the images created from reference. type ImageCreatedFrom struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/iso.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/iso.go similarity index 58% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/iso.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/iso.go index e1f38c10697a1..4cf48cc1aef7c 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/iso.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/iso.go @@ -1,15 +1,12 @@ package schema -import "time" - // ISO defines the schema of an ISO image. type ISO struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Type string `json:"type"` - Architecture *string `json:"architecture"` - Deprecated time.Time `json:"deprecated"` + ID int64 `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Type string `json:"type"` + Architecture *string `json:"architecture"` DeprecatableResource } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/load_balancer.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/load_balancer.go similarity index 90% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/load_balancer.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/load_balancer.go index 68adf5eb68694..d8760ad2633ad 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/load_balancer.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/load_balancer.go @@ -3,7 +3,7 @@ package schema import "time" type LoadBalancer struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` PublicNet LoadBalancerPublicNet `json:"public_net"` PrivateNet []LoadBalancerPrivateNet `json:"private_net"` @@ -37,7 +37,7 @@ type LoadBalancerPublicNetIPv6 struct { } type LoadBalancerPrivateNet struct { - Network int `json:"network"` + Network int64 `json:"network"` IP string `json:"ip"` } @@ -59,11 +59,11 @@ type LoadBalancerService struct { } type LoadBalancerServiceHTTP struct { - CookieName string `json:"cookie_name"` - CookieLifetime int `json:"cookie_lifetime"` - Certificates []int `json:"certificates"` - RedirectHTTP bool `json:"redirect_http"` - StickySessions bool `json:"sticky_sessions"` + CookieName string `json:"cookie_name"` + CookieLifetime int `json:"cookie_lifetime"` + Certificates []int64 `json:"certificates"` + RedirectHTTP bool `json:"redirect_http"` + StickySessions bool `json:"sticky_sessions"` } type LoadBalancerServiceHealthCheck struct { @@ -99,7 +99,7 @@ type LoadBalancerTargetHealthStatus struct { } type LoadBalancerTargetServer struct { - ID int `json:"id"` + ID int64 `json:"id"` } type LoadBalancerTargetLabelSelector struct { @@ -127,7 +127,7 @@ type LoadBalancerActionAddTargetRequest struct { } type LoadBalancerActionAddTargetRequestServer struct { - ID int `json:"id"` + ID int64 `json:"id"` } type LoadBalancerActionAddTargetRequestLabelSelector struct { @@ -150,7 +150,7 @@ type LoadBalancerActionRemoveTargetRequest struct { } type LoadBalancerActionRemoveTargetRequestServer struct { - ID int `json:"id"` + ID int64 `json:"id"` } type LoadBalancerActionRemoveTargetRequestLabelSelector struct { @@ -175,11 +175,11 @@ type LoadBalancerActionAddServiceRequest struct { } type LoadBalancerActionAddServiceRequestHTTP struct { - CookieName *string `json:"cookie_name,omitempty"` - CookieLifetime *int `json:"cookie_lifetime,omitempty"` - Certificates *[]int `json:"certificates,omitempty"` - RedirectHTTP *bool `json:"redirect_http,omitempty"` - StickySessions *bool `json:"sticky_sessions,omitempty"` + CookieName *string `json:"cookie_name,omitempty"` + CookieLifetime *int `json:"cookie_lifetime,omitempty"` + Certificates *[]int64 `json:"certificates,omitempty"` + RedirectHTTP *bool `json:"redirect_http,omitempty"` + StickySessions *bool `json:"sticky_sessions,omitempty"` } type LoadBalancerActionAddServiceRequestHealthCheck struct { @@ -213,11 +213,11 @@ type LoadBalancerActionUpdateServiceRequest struct { } type LoadBalancerActionUpdateServiceRequestHTTP struct { - CookieName *string `json:"cookie_name,omitempty"` - CookieLifetime *int `json:"cookie_lifetime,omitempty"` - Certificates *[]int `json:"certificates,omitempty"` - RedirectHTTP *bool `json:"redirect_http,omitempty"` - StickySessions *bool `json:"sticky_sessions,omitempty"` + CookieName *string `json:"cookie_name,omitempty"` + CookieLifetime *int `json:"cookie_lifetime,omitempty"` + Certificates *[]int64 `json:"certificates,omitempty"` + RedirectHTTP *bool `json:"redirect_http,omitempty"` + StickySessions *bool `json:"sticky_sessions,omitempty"` } type LoadBalancerActionUpdateServiceRequestHealthCheck struct { @@ -251,7 +251,7 @@ type LoadBalancerDeleteServiceResponse struct { type LoadBalancerCreateRequest struct { Name string `json:"name"` - LoadBalancerType interface{} `json:"load_balancer_type"` // int or string + LoadBalancerType IDOrName `json:"load_balancer_type"` Algorithm *LoadBalancerCreateRequestAlgorithm `json:"algorithm,omitempty"` Location *string `json:"location,omitempty"` NetworkZone *string `json:"network_zone,omitempty"` @@ -259,7 +259,7 @@ type LoadBalancerCreateRequest struct { Targets []LoadBalancerCreateRequestTarget `json:"targets,omitempty"` Services []LoadBalancerCreateRequestService `json:"services,omitempty"` PublicInterface *bool `json:"public_interface,omitempty"` - Network *int `json:"network,omitempty"` + Network *int64 `json:"network,omitempty"` } type LoadBalancerCreateRequestAlgorithm struct { @@ -275,7 +275,7 @@ type LoadBalancerCreateRequestTarget struct { } type LoadBalancerCreateRequestTargetServer struct { - ID int `json:"id"` + ID int64 `json:"id"` } type LoadBalancerCreateRequestTargetLabelSelector struct { @@ -296,11 +296,11 @@ type LoadBalancerCreateRequestService struct { } type LoadBalancerCreateRequestServiceHTTP struct { - CookieName *string `json:"cookie_name,omitempty"` - CookieLifetime *int `json:"cookie_lifetime,omitempty"` - Certificates *[]int `json:"certificates,omitempty"` - RedirectHTTP *bool `json:"redirect_http,omitempty"` - StickySessions *bool `json:"sticky_sessions,omitempty"` + CookieName *string `json:"cookie_name,omitempty"` + CookieLifetime *int `json:"cookie_lifetime,omitempty"` + Certificates *[]int64 `json:"certificates,omitempty"` + RedirectHTTP *bool `json:"redirect_http,omitempty"` + StickySessions *bool `json:"sticky_sessions,omitempty"` } type LoadBalancerCreateRequestServiceHealthCheck struct { @@ -351,7 +351,7 @@ type LoadBalancerActionChangeAlgorithmResponse struct { } type LoadBalancerActionAttachToNetworkRequest struct { - Network int `json:"network"` + Network int64 `json:"network"` IP *string `json:"ip,omitempty"` } @@ -360,7 +360,7 @@ type LoadBalancerActionAttachToNetworkResponse struct { } type LoadBalancerActionDetachFromNetworkRequest struct { - Network int `json:"network"` + Network int64 `json:"network"` } type LoadBalancerActionDetachFromNetworkResponse struct { @@ -380,7 +380,7 @@ type LoadBalancerActionDisablePublicInterfaceResponse struct { } type LoadBalancerActionChangeTypeRequest struct { - LoadBalancerType interface{} `json:"load_balancer_type"` // int or string + LoadBalancerType IDOrName `json:"load_balancer_type"` } type LoadBalancerActionChangeTypeResponse struct { diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/load_balancer_type.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/load_balancer_type.go similarity index 88% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/load_balancer_type.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/load_balancer_type.go index b0baf048914db..b0193d3a86f4d 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/load_balancer_type.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/load_balancer_type.go @@ -2,7 +2,7 @@ package schema // LoadBalancerType defines the schema of a LoadBalancer type. type LoadBalancerType struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Description string `json:"description"` MaxConnections int `json:"max_connections"` @@ -10,6 +10,7 @@ type LoadBalancerType struct { MaxTargets int `json:"max_targets"` MaxAssignedCertificates int `json:"max_assigned_certificates"` Prices []PricingLoadBalancerTypePrice `json:"prices"` + Deprecated *string `json:"deprecated"` } // LoadBalancerTypeListResponse defines the schema of the response when diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/location.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/location.go similarity index 95% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/location.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/location.go index 3dd58ad5e2910..e07306071c24f 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/location.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/location.go @@ -2,7 +2,7 @@ package schema // Location defines the schema of a location. type Location struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Description string `json:"description"` Country string `json:"country"` diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/meta.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/meta.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/meta.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/meta.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/network.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go similarity index 94% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/network.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go index 56bcbea9c7583..0e89c70eda8a4 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/network.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go @@ -4,13 +4,14 @@ import "time" // Network defines the schema of a network. type Network struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Created time.Time `json:"created"` IPRange string `json:"ip_range"` Subnets []NetworkSubnet `json:"subnets"` Routes []NetworkRoute `json:"routes"` - Servers []int `json:"servers"` + Servers []int64 `json:"servers"` + LoadBalancers []int64 `json:"load_balancers"` Protection NetworkProtection `json:"protection"` Labels map[string]string `json:"labels"` ExposeRoutesToVSwitch bool `json:"expose_routes_to_vswitch"` @@ -22,7 +23,7 @@ type NetworkSubnet struct { IPRange string `json:"ip_range"` NetworkZone string `json:"network_zone"` Gateway string `json:"gateway,omitempty"` - VSwitchID int `json:"vswitch_id,omitempty"` + VSwitchID int64 `json:"vswitch_id,omitempty"` } // NetworkRoute represents a route of a network. @@ -95,7 +96,7 @@ type NetworkActionAddSubnetRequest struct { IPRange string `json:"ip_range,omitempty"` NetworkZone string `json:"network_zone"` Gateway string `json:"gateway"` - VSwitchID int `json:"vswitch_id,omitempty"` + VSwitchID int64 `json:"vswitch_id,omitempty"` } // NetworkActionAddSubnetResponse defines the schema of the response when diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/placement_group.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/placement_group.go similarity index 92% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/placement_group.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/placement_group.go index 6bee4390c7711..671bd6bed81de 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/placement_group.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/placement_group.go @@ -3,11 +3,11 @@ package schema import "time" type PlacementGroup struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Labels map[string]string `json:"labels"` Created time.Time `json:"created"` - Servers []int `json:"servers"` + Servers []int64 `json:"servers"` Type string `json:"type"` } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/pricing.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/pricing.go similarity index 93% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/pricing.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/pricing.go index a863a57ac6a20..c1adbb1bd762e 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/pricing.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/pricing.go @@ -2,9 +2,10 @@ package schema // Pricing defines the schema for pricing information. type Pricing struct { - Currency string `json:"currency"` - VATRate string `json:"vat_rate"` - Image PricingImage `json:"image"` + Currency string `json:"currency"` + VATRate string `json:"vat_rate"` + Image PricingImage `json:"image"` + // Deprecated: [Pricing.FloatingIP] is deprecated, use [Pricing.FloatingIPs] instead. FloatingIP PricingFloatingIP `json:"floating_ip"` FloatingIPs []PricingFloatingIPType `json:"floating_ips"` PrimaryIPs []PricingPrimaryIP `json:"primary_ips"` @@ -63,7 +64,7 @@ type PricingServerBackup struct { // PricingServerType defines the schema of pricing information for a server type. type PricingServerType struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Prices []PricingServerTypePrice `json:"prices"` } @@ -81,7 +82,7 @@ type PricingServerTypePrice struct { // PricingLoadBalancerType defines the schema of pricing information for a Load Balancer type. type PricingLoadBalancerType struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Prices []PricingLoadBalancerTypePrice `json:"prices"` } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/primary_ip.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/primary_ip.go new file mode 100644 index 0000000000000..300711fc254e8 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/primary_ip.go @@ -0,0 +1,118 @@ +package schema + +import "time" + +// PrimaryIP defines a Primary IP. +type PrimaryIP struct { + ID int64 `json:"id"` + IP string `json:"ip"` + Labels map[string]string `json:"labels"` + Name string `json:"name"` + Type string `json:"type"` + Protection PrimaryIPProtection `json:"protection"` + DNSPtr []PrimaryIPDNSPTR `json:"dns_ptr"` + AssigneeID *int64 `json:"assignee_id"` + AssigneeType string `json:"assignee_type"` + AutoDelete bool `json:"auto_delete"` + Blocked bool `json:"blocked"` + Created time.Time `json:"created"` + Datacenter Datacenter `json:"datacenter"` +} + +// PrimaryIPProtection represents the protection level of a Primary IP. +type PrimaryIPProtection struct { + Delete bool `json:"delete"` +} + +// PrimaryIPDNSPTR contains reverse DNS information for a +// IPv4 or IPv6 Primary IP. +type PrimaryIPDNSPTR struct { + DNSPtr string `json:"dns_ptr"` + IP string `json:"ip"` +} + +// PrimaryIPCreateOpts defines the request to +// create a Primary IP. +type PrimaryIPCreateRequest struct { + Name string `json:"name"` + Type string `json:"type"` + AssigneeType string `json:"assignee_type"` + AssigneeID *int64 `json:"assignee_id,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + AutoDelete *bool `json:"auto_delete,omitempty"` + Datacenter string `json:"datacenter,omitempty"` +} + +// PrimaryIPCreateResponse defines the schema of the response +// when creating a Primary IP. +type PrimaryIPCreateResponse struct { + PrimaryIP PrimaryIP `json:"primary_ip"` + Action *Action `json:"action"` +} + +// PrimaryIPGetResponse defines the response when retrieving a single Primary IP. +type PrimaryIPGetResponse struct { + PrimaryIP PrimaryIP `json:"primary_ip"` +} + +// PrimaryIPListResponse defines the response when listing Primary IPs. +type PrimaryIPListResponse struct { + PrimaryIPs []PrimaryIP `json:"primary_ips"` +} + +// PrimaryIPUpdateOpts defines the request to +// update a Primary IP. +type PrimaryIPUpdateRequest struct { + Name string `json:"name,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + AutoDelete *bool `json:"auto_delete,omitempty"` +} + +// PrimaryIPUpdateResponse defines the response +// when updating a Primary IP. +type PrimaryIPUpdateResponse struct { + PrimaryIP PrimaryIP `json:"primary_ip"` +} + +// PrimaryIPActionChangeDNSPtrRequest defines the schema for the request to +// change a Primary IP's reverse DNS pointer. +type PrimaryIPActionChangeDNSPtrRequest struct { + IP string `json:"ip"` + DNSPtr *string `json:"dns_ptr"` +} + +// PrimaryIPActionChangeDNSPtrResponse defines the response when setting a reverse DNS +// pointer for a IP address. +type PrimaryIPActionChangeDNSPtrResponse struct { + Action Action `json:"action"` +} + +// PrimaryIPActionAssignRequest defines the request to +// assign a Primary IP to an assignee (usually a server). +type PrimaryIPActionAssignRequest struct { + AssigneeID int64 `json:"assignee_id"` + AssigneeType string `json:"assignee_type"` +} + +// PrimaryIPActionAssignResponse defines the response when assigning a Primary IP to a +// assignee. +type PrimaryIPActionAssignResponse struct { + Action Action `json:"action"` +} + +// PrimaryIPActionUnassignResponse defines the response to unassign a Primary IP. +type PrimaryIPActionUnassignResponse struct { + Action Action `json:"action"` +} + +// PrimaryIPActionChangeProtectionRequest defines the request to +// change protection configuration of a Primary IP. +type PrimaryIPActionChangeProtectionRequest struct { + Delete bool `json:"delete"` +} + +// PrimaryIPActionChangeProtectionResponse defines the response when changing the +// protection of a Primary IP. +type PrimaryIPActionChangeProtectionResponse struct { + Action Action `json:"action"` +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/server.go similarity index 90% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/server.go index 4786b1f9acc56..72aaf269de7bd 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/server.go @@ -4,7 +4,7 @@ import "time" // Server defines the schema of a server. type Server struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Status string `json:"status"` Created time.Time `json:"created"` @@ -22,9 +22,10 @@ type Server struct { Image *Image `json:"image"` Protection ServerProtection `json:"protection"` Labels map[string]string `json:"labels"` - Volumes []int `json:"volumes"` + Volumes []int64 `json:"volumes"` PrimaryDiskSize int `json:"primary_disk_size"` PlacementGroup *PlacementGroup `json:"placement_group"` + LoadBalancers []int64 `json:"load_balancers"` } // ServerProtection defines the schema of a server's resource protection. @@ -38,14 +39,14 @@ type ServerProtection struct { type ServerPublicNet struct { IPv4 ServerPublicNetIPv4 `json:"ipv4"` IPv6 ServerPublicNetIPv6 `json:"ipv6"` - FloatingIPs []int `json:"floating_ips"` + FloatingIPs []int64 `json:"floating_ips"` Firewalls []ServerFirewall `json:"firewalls"` } // ServerPublicNetIPv4 defines the schema of a server's public // network information for an IPv4. type ServerPublicNetIPv4 struct { - ID int `json:"id"` + ID int64 `json:"id"` IP string `json:"ip"` Blocked bool `json:"blocked"` DNSPtr string `json:"dns_ptr"` @@ -54,7 +55,7 @@ type ServerPublicNetIPv4 struct { // ServerPublicNetIPv6 defines the schema of a server's public // network information for an IPv6. type ServerPublicNetIPv6 struct { - ID int `json:"id"` + ID int64 `json:"id"` IP string `json:"ip"` Blocked bool `json:"blocked"` DNSPtr []ServerPublicNetIPv6DNSPtr `json:"dns_ptr"` @@ -70,13 +71,13 @@ type ServerPublicNetIPv6DNSPtr struct { // ServerFirewall defines the schema of a Server's Firewalls on // a certain network interface. type ServerFirewall struct { - ID int `json:"id"` + ID int64 `json:"id"` Status string `json:"status"` } // ServerPrivateNet defines the schema of a server's private network information. type ServerPrivateNet struct { - Network int `json:"network"` + Network int64 `json:"network"` IP string `json:"ip"` AliasIPs []string `json:"alias_ips"` MACAddress string `json:"mac_address"` @@ -98,33 +99,33 @@ type ServerListResponse struct { // create a server. type ServerCreateRequest struct { Name string `json:"name"` - ServerType interface{} `json:"server_type"` // int or string - Image interface{} `json:"image"` // int or string - SSHKeys []int `json:"ssh_keys,omitempty"` + ServerType IDOrName `json:"server_type"` + Image IDOrName `json:"image"` + SSHKeys []int64 `json:"ssh_keys,omitempty"` Location string `json:"location,omitempty"` Datacenter string `json:"datacenter,omitempty"` UserData string `json:"user_data,omitempty"` StartAfterCreate *bool `json:"start_after_create,omitempty"` Labels *map[string]string `json:"labels,omitempty"` Automount *bool `json:"automount,omitempty"` - Volumes []int `json:"volumes,omitempty"` - Networks []int `json:"networks,omitempty"` + Volumes []int64 `json:"volumes,omitempty"` + Networks []int64 `json:"networks,omitempty"` Firewalls []ServerCreateFirewalls `json:"firewalls,omitempty"` - PlacementGroup int `json:"placement_group,omitempty"` + PlacementGroup int64 `json:"placement_group,omitempty"` PublicNet *ServerCreatePublicNet `json:"public_net,omitempty"` } // ServerCreatePublicNet defines the public network configuration of a server. type ServerCreatePublicNet struct { - EnableIPv4 bool `json:"enable_ipv4"` - EnableIPv6 bool `json:"enable_ipv6"` - IPv4ID int `json:"ipv4,omitempty"` - IPv6ID int `json:"ipv6,omitempty"` + EnableIPv4 bool `json:"enable_ipv4"` + EnableIPv6 bool `json:"enable_ipv6"` + IPv4ID int64 `json:"ipv4,omitempty"` + IPv6ID int64 `json:"ipv6,omitempty"` } // ServerCreateFirewalls defines which Firewalls to apply when creating a Server. type ServerCreateFirewalls struct { - Firewall int `json:"firewall"` + Firewall int64 `json:"firewall"` } // ServerCreateResponse defines the schema of the response when @@ -233,7 +234,7 @@ type ServerActionCreateImageResponse struct { // create a enable_rescue server action. type ServerActionEnableRescueRequest struct { Type *string `json:"type,omitempty"` - SSHKeys []int `json:"ssh_keys,omitempty"` + SSHKeys []int64 `json:"ssh_keys,omitempty"` } // ServerActionEnableRescueResponse defines the schema of the response when @@ -256,7 +257,7 @@ type ServerActionDisableRescueResponse struct { // ServerActionRebuildRequest defines the schema for the request to // rebuild a server. type ServerActionRebuildRequest struct { - Image interface{} `json:"image"` // int or string + Image IDOrName `json:"image"` } // ServerActionRebuildResponse defines the schema of the response when @@ -269,7 +270,7 @@ type ServerActionRebuildResponse struct { // ServerActionAttachISORequest defines the schema for the request to // attach an ISO to a server. type ServerActionAttachISORequest struct { - ISO interface{} `json:"iso"` // int or string + ISO IDOrName `json:"iso"` } // ServerActionAttachISOResponse defines the schema of the response when @@ -288,12 +289,6 @@ type ServerActionDetachISOResponse struct { Action Action `json:"action"` } -// ServerActionEnableBackupRequest defines the schema for the request to -// enable backup for a server. -type ServerActionEnableBackupRequest struct { - BackupWindow *string `json:"backup_window,omitempty"` -} - // ServerActionEnableBackupResponse defines the schema of the response when // creating a enable_backup server action. type ServerActionEnableBackupResponse struct { @@ -313,8 +308,8 @@ type ServerActionDisableBackupResponse struct { // ServerActionChangeTypeRequest defines the schema for the request to // change a server's type. type ServerActionChangeTypeRequest struct { - ServerType interface{} `json:"server_type"` // int or string - UpgradeDisk bool `json:"upgrade_disk"` + ServerType IDOrName `json:"server_type"` + UpgradeDisk bool `json:"upgrade_disk"` } // ServerActionChangeTypeResponse defines the schema of the response when @@ -364,7 +359,7 @@ type ServerActionRequestConsoleResponse struct { // ServerActionAttachToNetworkRequest defines the schema for the request to // attach a network to a server. type ServerActionAttachToNetworkRequest struct { - Network int `json:"network"` + Network int64 `json:"network"` IP *string `json:"ip,omitempty"` AliasIPs []*string `json:"alias_ips,omitempty"` } @@ -378,7 +373,7 @@ type ServerActionAttachToNetworkResponse struct { // ServerActionDetachFromNetworkRequest defines the schema for the request to // detach a network from a server. type ServerActionDetachFromNetworkRequest struct { - Network int `json:"network"` + Network int64 `json:"network"` } // ServerActionDetachFromNetworkResponse defines the schema of the response when @@ -390,7 +385,7 @@ type ServerActionDetachFromNetworkResponse struct { // ServerActionChangeAliasIPsRequest defines the schema for the request to // change a server's alias IPs in a network. type ServerActionChangeAliasIPsRequest struct { - Network int `json:"network"` + Network int64 `json:"network"` AliasIPs []string `json:"alias_ips"` } @@ -419,7 +414,7 @@ type ServerTimeSeriesVals struct { // ServerActionAddToPlacementGroupRequest defines the schema for the request to // add a server to a placement group. type ServerActionAddToPlacementGroupRequest struct { - PlacementGroup int `json:"placement_group"` + PlacementGroup int64 `json:"placement_group"` } // ServerActionAddToPlacementGroupResponse defines the schema of the response when diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server_type.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/server_type.go similarity index 92% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server_type.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/server_type.go index db6224499b249..60f43a1bf860f 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/server_type.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/server_type.go @@ -2,7 +2,7 @@ package schema // ServerType defines the schema of a server type. type ServerType struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Description string `json:"description"` Cores int `json:"cores"` @@ -16,6 +16,7 @@ type ServerType struct { // Use [ServerType.Prices] instead to get the included traffic for each location. IncludedTraffic int64 `json:"included_traffic"` Prices []PricingServerTypePrice `json:"prices"` + Deprecated bool `json:"deprecated"` DeprecatableResource } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/ssh_key.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/ssh_key.go similarity index 97% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/ssh_key.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/ssh_key.go index f230b3ddd122a..7e095bc5a7fa9 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/ssh_key.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/ssh_key.go @@ -4,7 +4,7 @@ import "time" // SSHKey defines the schema of a SSH key. type SSHKey struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` Fingerprint string `json:"fingerprint"` PublicKey string `json:"public_key"` diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/volume.go similarity index 93% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/volume.go index 19c741c125c59..89223ba43afe7 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/schema/volume.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/volume.go @@ -4,9 +4,9 @@ import "time" // Volume defines the schema of a volume. type Volume struct { - ID int `json:"id"` + ID int64 `json:"id"` Name string `json:"name"` - Server *int `json:"server"` + Server *int64 `json:"server"` Status string `json:"status"` Location Location `json:"location"` Size int `json:"size"` @@ -22,8 +22,8 @@ type Volume struct { type VolumeCreateRequest struct { Name string `json:"name"` Size int `json:"size"` - Server *int `json:"server,omitempty"` - Location interface{} `json:"location,omitempty"` // int, string, or nil + Server *int64 `json:"server,omitempty"` + Location *IDOrName `json:"location,omitempty"` Labels *map[string]string `json:"labels,omitempty"` Automount *bool `json:"automount,omitempty"` Format *string `json:"format,omitempty"` @@ -80,7 +80,7 @@ type VolumeActionChangeProtectionResponse struct { // VolumeActionAttachVolumeRequest defines the schema of the request to // attach a volume to a server. type VolumeActionAttachVolumeRequest struct { - Server int `json:"server"` + Server int64 `json:"server"` Automount *bool `json:"automount,omitempty"` } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_assign.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_assign.go new file mode 100644 index 0000000000000..8894e35069164 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_assign.go @@ -0,0 +1,15 @@ +//go:build !goverter + +package hcloud + +/* +This file is needed so that c is assigned to a converterImpl{}. +If we did this in schema.go, goverter would fail because of a +compiler error (converterImpl might not be defined). +Because this file is not compiled by goverter, we can safely +assign c here. +*/ + +func init() { + c = &converterImpl{} +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go new file mode 100644 index 0000000000000..e502e41e4988a --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go @@ -0,0 +1,984 @@ +package hcloud + +import ( + "encoding/json" + "fmt" + "net" + "time" + + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" +) + +//go:generate go run github.com/jmattheis/goverter/cmd/goverter gen ./... + +/* +This file generates conversions methods between the schema and the hcloud package. +Goverter (https://github.com/jmattheis/goverter) is used to generate these conversion +methods. Goverter is configured using comments in and on the [converter] interface. +A struct implementing the interface methods, [converterImpl], is generated in zz_schema.go. +The generated methods are then wrapped in schema.go to be exported. + +You can find a documentation of goverter here: https://goverter.jmattheis.de/ +*/ + +// goverter:converter +// +// Specify where and in which package to output the generated +// conversion methods. +// goverter:output:file zz_schema.go +// goverter:output:package github.com/hetznercloud/hcloud-go/v2/hcloud +// +// In case of *T -> T conversion, use zero value if *T is nil. +// goverter:useZeroValueOnPointerInconsistency yes +// +// Do not deep copy in case of *T -> *T conversion. +// goverter:skipCopySameType yes +// +// Explicit conversion methods are needed for non-trivial cases +// where the target, source or both are of primitive types. Struct +// to struct conversions can be handled by goverter directly. +// goverter:extend ipFromString +// goverter:extend stringFromIP +// goverter:extend ipNetFromString +// goverter:extend stringFromIPNet +// goverter:extend timeToTimePtr +// goverter:extend serverFromInt64 +// goverter:extend int64FromServer +// goverter:extend networkFromInt64 +// goverter:extend int64FromNetwork +// goverter:extend loadBalancerFromInt64 +// goverter:extend int64FromLoadBalancer +// goverter:extend volumeFromInt64 +// goverter:extend int64FromVolume +// goverter:extend certificateFromInt64 +// goverter:extend int64FromCertificate +// goverter:extend locationFromString +// goverter:extend stringFromLocation +// goverter:extend serverTypeFromInt64 +// goverter:extend int64FromServerType +// goverter:extend floatingIPFromInt64 +// goverter:extend int64FromFloatingIP +// goverter:extend mapFromFloatingIPDNSPtrSchema +// goverter:extend floatingIPDNSPtrSchemaFromMap +// goverter:extend mapFromPrimaryIPDNSPtrSchema +// goverter:extend primaryIPDNSPtrSchemaFromMap +// goverter:extend mapFromServerPublicNetIPv6DNSPtrSchema +// goverter:extend serverPublicNetIPv6DNSPtrSchemaFromMap +// goverter:extend firewallStatusFromSchemaServerFirewall +// goverter:extend serverFirewallSchemaFromFirewallStatus +// goverter:extend durationFromIntSeconds +// goverter:extend intSecondsFromDuration +// goverter:extend serverFromImageCreatedFromSchema +// goverter:extend serverMetricsTimeSeriesFromSchema +// goverter:extend loadBalancerMetricsTimeSeriesFromSchema +// goverter:extend stringPtrFromLoadBalancerServiceProtocol +// goverter:extend stringPtrFromNetworkZone +// goverter:extend schemaFromLoadBalancerCreateOptsTargetLabelSelector +// goverter:extend schemaFromLoadBalancerCreateOptsTargetServer +// goverter:extend schemaFromLoadBalancerCreateOptsTargetIP +// goverter:extend stringMapToStringMapPtr +// goverter:extend int64SlicePtrFromCertificatePtrSlice +// goverter:extend stringSlicePtrFromStringSlice +type converter interface { + + // goverter:map Error.Code ErrorCode + // goverter:map Error.Message ErrorMessage + ActionFromSchema(schema.Action) *Action + + // goverter:map . Error | schemaActionErrorFromAction + SchemaFromAction(*Action) schema.Action + + ActionsFromSchema([]schema.Action) []*Action + + SchemaFromActions([]*Action) []schema.Action + + // goverter:map . IP | ipFromFloatingIPSchema + // goverter:map . Network | networkFromFloatingIPSchema + FloatingIPFromSchema(schema.FloatingIP) *FloatingIP + + // goverter:map . IP | floatingIPToIPString + SchemaFromFloatingIP(*FloatingIP) schema.FloatingIP + + // goverter:map . IP | ipFromPrimaryIPSchema + // goverter:map . Network | networkFromPrimaryIPSchema + PrimaryIPFromSchema(schema.PrimaryIP) *PrimaryIP + + // goverter:map . IP | primaryIPToIPString + // goverter:map AssigneeID | mapZeroInt64ToNil + SchemaFromPrimaryIP(*PrimaryIP) schema.PrimaryIP + + SchemaFromPrimaryIPCreateOpts(PrimaryIPCreateOpts) schema.PrimaryIPCreateRequest + SchemaFromPrimaryIPUpdateOpts(PrimaryIPUpdateOpts) schema.PrimaryIPUpdateRequest + SchemaFromPrimaryIPChangeDNSPtrOpts(PrimaryIPChangeDNSPtrOpts) schema.PrimaryIPActionChangeDNSPtrRequest + SchemaFromPrimaryIPChangeProtectionOpts(PrimaryIPChangeProtectionOpts) schema.PrimaryIPActionChangeProtectionRequest + SchemaFromPrimaryIPAssignOpts(PrimaryIPAssignOpts) schema.PrimaryIPActionAssignRequest + + ISOFromSchema(schema.ISO) *ISO + + // We cannot use goverter settings when mapping a struct to a struct pointer + // See [converter.ISOFromSchema] + // See https://github.com/jmattheis/goverter/issues/114 + // goverter:map DeprecatableResource.Deprecation.UnavailableAfter Deprecated + intISOFromSchema(schema.ISO) ISO + + SchemaFromISO(*ISO) schema.ISO + + LocationFromSchema(schema.Location) *Location + + SchemaFromLocation(*Location) schema.Location + + DatacenterFromSchema(schema.Datacenter) *Datacenter + + SchemaFromDatacenter(*Datacenter) schema.Datacenter + + ServerFromSchema(schema.Server) *Server + + // goverter:map OutgoingTraffic | mapZeroUint64ToNil + // goverter:map IngoingTraffic | mapZeroUint64ToNil + // goverter:map BackupWindow | mapEmptyStringToNil + SchemaFromServer(*Server) schema.Server + + ServerPublicNetFromSchema(schema.ServerPublicNet) ServerPublicNet + + SchemaFromServerPublicNet(ServerPublicNet) schema.ServerPublicNet + + ServerPublicNetIPv4FromSchema(schema.ServerPublicNetIPv4) ServerPublicNetIPv4 + + SchemaFromServerPublicNetIPv4(ServerPublicNetIPv4) schema.ServerPublicNetIPv4 + + // goverter:map . IP | ipFromServerPublicNetIPv6Schema + // goverter:map . Network | ipNetFromServerPublicNetIPv6Schema + ServerPublicNetIPv6FromSchema(schema.ServerPublicNetIPv6) ServerPublicNetIPv6 + + // goverter:map Network IP + SchemaFromServerPublicNetIPv6(ServerPublicNetIPv6) schema.ServerPublicNetIPv6 + + // goverter:map AliasIPs Aliases + ServerPrivateNetFromSchema(schema.ServerPrivateNet) ServerPrivateNet + + // goverter:map Aliases AliasIPs + SchemaFromServerPrivateNet(ServerPrivateNet) schema.ServerPrivateNet + + // goverter:map Prices Pricings + ServerTypeFromSchema(schema.ServerType) *ServerType + + // goverter:map Pricings Prices + // goverter:map DeprecatableResource.Deprecation Deprecated | isDeprecationNotNil + SchemaFromServerType(*ServerType) schema.ServerType + + ImageFromSchema(schema.Image) *Image + + SchemaFromImage(*Image) schema.Image + + // Needed because of how goverter works internally, see https://github.com/jmattheis/goverter/issues/114 + // goverter:map ImageSize | mapZeroFloat32ToNil + intSchemaFromImage(Image) schema.Image + + // goverter:ignore Currency + // goverter:ignore VATRate + PriceFromSchema(schema.Price) Price + + SSHKeyFromSchema(schema.SSHKey) *SSHKey + + SchemaFromSSHKey(*SSHKey) schema.SSHKey + + VolumeFromSchema(schema.Volume) *Volume + + SchemaFromVolume(*Volume) schema.Volume + + NetworkFromSchema(schema.Network) *Network + + SchemaFromNetwork(*Network) schema.Network + + NetworkSubnetFromSchema(schema.NetworkSubnet) NetworkSubnet + + SchemaFromNetworkSubnet(NetworkSubnet) schema.NetworkSubnet + + NetworkRouteFromSchema(schema.NetworkRoute) NetworkRoute + + SchemaFromNetworkRoute(NetworkRoute) schema.NetworkRoute + + LoadBalancerFromSchema(schema.LoadBalancer) *LoadBalancer + + // goverter:map OutgoingTraffic | mapZeroUint64ToNil + // goverter:map IngoingTraffic | mapZeroUint64ToNil + SchemaFromLoadBalancer(*LoadBalancer) schema.LoadBalancer + + // goverter:map Prices Pricings + LoadBalancerTypeFromSchema(schema.LoadBalancerType) *LoadBalancerType + + // goverter:map Pricings Prices + SchemaFromLoadBalancerType(*LoadBalancerType) schema.LoadBalancerType + + // goverter:map PriceHourly Hourly + // goverter:map PriceMonthly Monthly + // goverter:map PricePerTBTraffic PerTBTraffic + LoadBalancerTypeLocationPricingFromSchema(schema.PricingLoadBalancerTypePrice) LoadBalancerTypeLocationPricing + + // goverter:map Hourly PriceHourly + // goverter:map Monthly PriceMonthly + // goverter:map PerTBTraffic PricePerTBTraffic + SchemaFromLoadBalancerTypeLocationPricing(LoadBalancerTypeLocationPricing) schema.PricingLoadBalancerTypePrice + + LoadBalancerServiceFromSchema(schema.LoadBalancerService) LoadBalancerService + + SchemaFromLoadBalancerService(LoadBalancerService) schema.LoadBalancerService + + LoadBalancerServiceHealthCheckFromSchema(*schema.LoadBalancerServiceHealthCheck) LoadBalancerServiceHealthCheck + + SchemaFromLoadBalancerServiceHealthCheck(LoadBalancerServiceHealthCheck) *schema.LoadBalancerServiceHealthCheck + + LoadBalancerTargetFromSchema(schema.LoadBalancerTarget) LoadBalancerTarget + + SchemaFromLoadBalancerTarget(LoadBalancerTarget) schema.LoadBalancerTarget + + // goverter:map ID Server + LoadBalancerTargetServerFromSchema(schema.LoadBalancerTargetServer) LoadBalancerTargetServer + + // goverter:map Server ID + SchemaFromLoadBalancerServerTarget(LoadBalancerTargetServer) schema.LoadBalancerTargetServer + + LoadBalancerTargetHealthStatusFromSchema(schema.LoadBalancerTargetHealthStatus) LoadBalancerTargetHealthStatus + + SchemaFromLoadBalancerTargetHealthStatus(LoadBalancerTargetHealthStatus) schema.LoadBalancerTargetHealthStatus + + CertificateFromSchema(schema.Certificate) *Certificate + + SchemaFromCertificate(*Certificate) schema.Certificate + + PaginationFromSchema(schema.MetaPagination) Pagination + + SchemaFromPagination(Pagination) schema.MetaPagination + + // goverter:ignore response + // goverter:map Details | errorDetailsFromSchema + ErrorFromSchema(schema.Error) Error + + // goverter:map Details | schemaFromErrorDetails + // goverter:map Details DetailsRaw | rawSchemaFromErrorDetails + SchemaFromError(Error) schema.Error + + // goverter:map . Image | imagePricingFromSchema + // goverter:map . FloatingIP | floatingIPPricingFromSchema + // goverter:map . FloatingIPs | floatingIPTypePricingFromSchema + // goverter:map . PrimaryIPs | primaryIPPricingFromSchema + // goverter:map . Traffic | trafficPricingFromSchema + // goverter:map . ServerTypes | serverTypePricingFromSchema + // goverter:map . LoadBalancerTypes | loadBalancerTypePricingFromSchema + // goverter:map . Volume | volumePricingFromSchema + PricingFromSchema(schema.Pricing) Pricing + + // goverter:map PriceHourly Hourly + // goverter:map PriceMonthly Monthly + // goverter:map PricePerTBTraffic PerTBTraffic + serverTypePricingFromSchema(schema.PricingServerTypePrice) ServerTypeLocationPricing + + // goverter:map Image.PerGBMonth.Currency Currency + // goverter:map Image.PerGBMonth.VATRate VATRate + SchemaFromPricing(Pricing) schema.Pricing + + // goverter:map PerGBMonth PricePerGBMonth + schemaFromImagePricing(ImagePricing) schema.PricingImage + + // goverter:map Monthly PriceMonthly + schemaFromFloatingIPPricing(FloatingIPPricing) schema.PricingFloatingIP + + // goverter:map Pricings Prices + schemaFromFloatingIPTypePricing(FloatingIPTypePricing) schema.PricingFloatingIPType + + // goverter:map Monthly PriceMonthly + schemaFromFloatingIPTypeLocationPricing(FloatingIPTypeLocationPricing) schema.PricingFloatingIPTypePrice + + // goverter:map Pricings Prices + schemaFromPrimaryIPPricing(PrimaryIPPricing) schema.PricingPrimaryIP + + // goverter:map Monthly PriceMonthly + // goverter:map Hourly PriceHourly + schemaFromPrimaryIPTypePricing(PrimaryIPTypePricing) schema.PricingPrimaryIPTypePrice + + // goverter:map PerTB PricePerTB + schemaFromTrafficPricing(TrafficPricing) schema.PricingTraffic + + // goverter:map Pricings Prices + // goverter:map ServerType.ID ID + // goverter:map ServerType.Name Name + schemaFromServerTypePricing(ServerTypePricing) schema.PricingServerType + + // goverter:map Pricings Prices + // goverter:map LoadBalancerType.ID ID + // goverter:map LoadBalancerType.Name Name + schemaFromLoadBalancerTypePricing(LoadBalancerTypePricing) schema.PricingLoadBalancerType + + // goverter:map PerGBMonthly PricePerGBPerMonth + schemaFromVolumePricing(VolumePricing) schema.PricingVolume + + // goverter:map Monthly PriceMonthly + // goverter:map Hourly PriceHourly + // goverter:map PerTBTraffic PricePerTBTraffic + schemaFromServerTypeLocationPricing(ServerTypeLocationPricing) schema.PricingServerTypePrice + + FirewallFromSchema(schema.Firewall) *Firewall + + SchemaFromFirewall(*Firewall) schema.Firewall + + PlacementGroupFromSchema(schema.PlacementGroup) *PlacementGroup + + SchemaFromPlacementGroup(*PlacementGroup) schema.PlacementGroup + + SchemaFromPlacementGroupCreateOpts(PlacementGroupCreateOpts) schema.PlacementGroupCreateRequest + + SchemaFromLoadBalancerCreateOpts(LoadBalancerCreateOpts) schema.LoadBalancerCreateRequest + + // goverter:map Server.ID ID + SchemaFromLoadBalancerCreateOptsTargetServer(LoadBalancerCreateOptsTargetServer) schema.LoadBalancerCreateRequestTargetServer + + SchemaFromLoadBalancerAddServiceOpts(LoadBalancerAddServiceOpts) schema.LoadBalancerActionAddServiceRequest + + // goverter:ignore ListenPort + SchemaFromLoadBalancerUpdateServiceOpts(LoadBalancerUpdateServiceOpts) schema.LoadBalancerActionUpdateServiceRequest + + SchemaFromFirewallCreateOpts(FirewallCreateOpts) schema.FirewallCreateRequest + + SchemaFromFirewallSetRulesOpts(FirewallSetRulesOpts) schema.FirewallActionSetRulesRequest + + SchemaFromFirewallResource(FirewallResource) schema.FirewallResource + + // goverter:autoMap Metrics + ServerMetricsFromSchema(*schema.ServerGetMetricsResponse) (*ServerMetrics, error) + + // goverter:autoMap Metrics + LoadBalancerMetricsFromSchema(*schema.LoadBalancerGetMetricsResponse) (*LoadBalancerMetrics, error) + + DeprecationFromSchema(*schema.DeprecationInfo) *DeprecationInfo + + SchemaFromDeprecation(*DeprecationInfo) *schema.DeprecationInfo +} + +func schemaActionErrorFromAction(a Action) *schema.ActionError { + if a.ErrorCode != "" && a.ErrorMessage != "" { + return &schema.ActionError{ + Code: a.ErrorCode, + Message: a.ErrorMessage, + } + } + return nil +} + +func ipFromFloatingIPSchema(s schema.FloatingIP) net.IP { + if s.Type == string(FloatingIPTypeIPv4) { + return net.ParseIP(s.IP) + } + ip, _, _ := net.ParseCIDR(s.IP) + return ip +} + +func networkFromFloatingIPSchema(s schema.FloatingIP) *net.IPNet { + if s.Type == string(FloatingIPTypeIPv4) { + return nil + } + _, n, _ := net.ParseCIDR(s.IP) + return n +} + +func ipFromPrimaryIPSchema(s schema.PrimaryIP) net.IP { + if s.Type == string(FloatingIPTypeIPv4) { + return net.ParseIP(s.IP) + } + ip, _, _ := net.ParseCIDR(s.IP) + return ip +} + +func networkFromPrimaryIPSchema(s schema.PrimaryIP) *net.IPNet { + if s.Type == string(FloatingIPTypeIPv4) { + return nil + } + _, n, _ := net.ParseCIDR(s.IP) + return n +} + +func serverFromInt64(id int64) Server { + return Server{ID: id} +} + +func int64FromServer(s Server) int64 { + return s.ID +} + +func networkFromInt64(id int64) Network { + return Network{ID: id} +} + +func int64FromNetwork(network Network) int64 { + return network.ID +} + +func loadBalancerFromInt64(id int64) LoadBalancer { + return LoadBalancer{ID: id} +} + +func int64FromLoadBalancer(lb LoadBalancer) int64 { + return lb.ID +} + +func volumeFromInt64(id int64) *Volume { + return &Volume{ID: id} +} + +func int64FromVolume(volume *Volume) int64 { + if volume == nil { + return 0 + } + return volume.ID +} + +func serverTypeFromInt64(id int64) *ServerType { + return &ServerType{ID: id} +} + +func int64FromServerType(s *ServerType) int64 { + if s == nil { + return 0 + } + return s.ID +} + +func certificateFromInt64(id int64) *Certificate { + return &Certificate{ID: id} +} + +func int64FromCertificate(c *Certificate) int64 { + if c == nil { + return 0 + } + return c.ID +} + +func locationFromString(s string) Location { + return Location{Name: s} +} + +func stringFromLocation(l Location) string { + return l.Name +} + +func mapFromFloatingIPDNSPtrSchema(dnsPtr []schema.FloatingIPDNSPtr) map[string]string { + m := make(map[string]string, len(dnsPtr)) + for _, entry := range dnsPtr { + m[entry.IP] = entry.DNSPtr + } + return m +} + +func floatingIPDNSPtrSchemaFromMap(m map[string]string) []schema.FloatingIPDNSPtr { + dnsPtr := make([]schema.FloatingIPDNSPtr, 0, len(m)) + for ip, ptr := range m { + dnsPtr = append(dnsPtr, schema.FloatingIPDNSPtr{ + IP: ip, + DNSPtr: ptr, + }) + } + return dnsPtr +} + +func mapFromPrimaryIPDNSPtrSchema(dnsPtr []schema.PrimaryIPDNSPTR) map[string]string { + m := make(map[string]string, len(dnsPtr)) + for _, entry := range dnsPtr { + m[entry.IP] = entry.DNSPtr + } + return m +} + +func primaryIPDNSPtrSchemaFromMap(m map[string]string) []schema.PrimaryIPDNSPTR { + dnsPtr := make([]schema.PrimaryIPDNSPTR, 0, len(m)) + for ip, ptr := range m { + dnsPtr = append(dnsPtr, schema.PrimaryIPDNSPTR{ + IP: ip, + DNSPtr: ptr, + }) + } + return dnsPtr +} + +func mapFromServerPublicNetIPv6DNSPtrSchema(dnsPtr []schema.ServerPublicNetIPv6DNSPtr) map[string]string { + m := make(map[string]string, len(dnsPtr)) + for _, entry := range dnsPtr { + m[entry.IP] = entry.DNSPtr + } + return m +} + +func serverPublicNetIPv6DNSPtrSchemaFromMap(m map[string]string) []schema.ServerPublicNetIPv6DNSPtr { + dnsPtr := make([]schema.ServerPublicNetIPv6DNSPtr, 0, len(m)) + for ip, ptr := range m { + dnsPtr = append(dnsPtr, schema.ServerPublicNetIPv6DNSPtr{ + IP: ip, + DNSPtr: ptr, + }) + } + return dnsPtr +} + +func floatingIPToIPString(ip FloatingIP) string { + if ip.Type == FloatingIPTypeIPv4 { + return ip.IP.String() + } + return ip.Network.String() +} + +func primaryIPToIPString(ip PrimaryIP) string { + if ip.Type == PrimaryIPTypeIPv4 { + return ip.IP.String() + } + return ip.Network.String() +} + +func floatingIPFromInt64(id int64) *FloatingIP { + return &FloatingIP{ID: id} +} + +func int64FromFloatingIP(f *FloatingIP) int64 { + if f == nil { + return 0 + } + return f.ID +} + +func firewallStatusFromSchemaServerFirewall(fw schema.ServerFirewall) *ServerFirewallStatus { + return &ServerFirewallStatus{ + Firewall: Firewall{ID: fw.ID}, + Status: FirewallStatus(fw.Status), + } +} + +func serverFirewallSchemaFromFirewallStatus(s *ServerFirewallStatus) schema.ServerFirewall { + return schema.ServerFirewall{ + ID: s.Firewall.ID, + Status: string(s.Status), + } +} + +func ipFromServerPublicNetIPv6Schema(s schema.ServerPublicNetIPv6) net.IP { + ip, _, _ := net.ParseCIDR(s.IP) + return ip +} + +func ipNetFromServerPublicNetIPv6Schema(s schema.ServerPublicNetIPv6) *net.IPNet { + _, n, _ := net.ParseCIDR(s.IP) + return n +} + +func serverFromImageCreatedFromSchema(s schema.ImageCreatedFrom) Server { + return Server{ + ID: s.ID, + Name: s.Name, + } +} + +func ipFromString(s string) net.IP { + return net.ParseIP(s) +} + +func stringFromIP(ip net.IP) string { + if ip == nil { + return "" + } + return ip.String() +} + +func ipNetFromString(s string) net.IPNet { + _, n, _ := net.ParseCIDR(s) + if n == nil { + return net.IPNet{} + } + return *n +} + +func stringFromIPNet(ip net.IPNet) string { + return ip.String() +} + +func timeToTimePtr(t time.Time) *time.Time { + // Some hcloud structs don't use pointers for nullable times, so the zero value + // should be treated as nil. + if t == (time.Time{}) { + return nil + } + return &t +} + +func durationFromIntSeconds(s int) time.Duration { + return time.Duration(s) * time.Second +} + +func intSecondsFromDuration(d time.Duration) int { + return int(d.Seconds()) +} + +func errorDetailsFromSchema(d interface{}) interface{} { + switch typed := d.(type) { + case schema.ErrorDetailsInvalidInput: + details := ErrorDetailsInvalidInput{ + Fields: make([]ErrorDetailsInvalidInputField, len(typed.Fields)), + } + for i, field := range typed.Fields { + details.Fields[i] = ErrorDetailsInvalidInputField{ + Name: field.Name, + Messages: field.Messages, + } + } + return details + + case schema.ErrorDetailsDeprecatedAPIEndpoint: + return ErrorDetailsDeprecatedAPIEndpoint{ + Announcement: typed.Announcement, + } + } + return nil +} + +func schemaFromErrorDetails(d interface{}) interface{} { + switch typed := d.(type) { + case ErrorDetailsInvalidInput: + details := schema.ErrorDetailsInvalidInput{ + Fields: make([]struct { + Name string `json:"name"` + Messages []string `json:"messages"` + }, len(typed.Fields)), + } + for i, field := range typed.Fields { + details.Fields[i] = struct { + Name string `json:"name"` + Messages []string `json:"messages"` + }{Name: field.Name, Messages: field.Messages} + } + return details + + case ErrorDetailsDeprecatedAPIEndpoint: + return schema.ErrorDetailsDeprecatedAPIEndpoint{Announcement: typed.Announcement} + } + + return nil +} + +func imagePricingFromSchema(s schema.Pricing) ImagePricing { + return ImagePricing{ + PerGBMonth: Price{ + Net: s.Image.PricePerGBMonth.Net, + Gross: s.Image.PricePerGBMonth.Gross, + Currency: s.Currency, + VATRate: s.VATRate, + }, + } +} + +func floatingIPPricingFromSchema(s schema.Pricing) FloatingIPPricing { + return FloatingIPPricing{ + Monthly: Price{ + Net: s.FloatingIP.PriceMonthly.Net, // nolint:staticcheck // Field is deprecated, but removal is not planned + Gross: s.FloatingIP.PriceMonthly.Gross, // nolint:staticcheck // Field is deprecated, but removal is not planned + Currency: s.Currency, + VATRate: s.VATRate, + }, + } +} + +func floatingIPTypePricingFromSchema(s schema.Pricing) []FloatingIPTypePricing { + p := make([]FloatingIPTypePricing, len(s.FloatingIPs)) + for i, floatingIPType := range s.FloatingIPs { + var pricings = make([]FloatingIPTypeLocationPricing, len(floatingIPType.Prices)) + for i, price := range floatingIPType.Prices { + pricings[i] = FloatingIPTypeLocationPricing{ + Location: &Location{Name: price.Location}, + Monthly: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PriceMonthly.Net, + Gross: price.PriceMonthly.Gross, + }, + } + } + p[i] = FloatingIPTypePricing{Type: FloatingIPType(floatingIPType.Type), Pricings: pricings} + } + return p +} + +func primaryIPPricingFromSchema(s schema.Pricing) []PrimaryIPPricing { + p := make([]PrimaryIPPricing, len(s.FloatingIPs)) + for i, primaryIPType := range s.PrimaryIPs { + var pricings = make([]PrimaryIPTypePricing, len(primaryIPType.Prices)) + for i, price := range primaryIPType.Prices { + pricings[i] = PrimaryIPTypePricing{ + Location: price.Location, + Monthly: PrimaryIPPrice{ + Net: price.PriceMonthly.Net, + Gross: price.PriceMonthly.Gross, + }, + Hourly: PrimaryIPPrice{ + Net: price.PriceHourly.Net, + Gross: price.PriceHourly.Gross, + }, + } + } + p[i] = PrimaryIPPricing{Type: primaryIPType.Type, Pricings: pricings} + } + return p +} + +func trafficPricingFromSchema(s schema.Pricing) TrafficPricing { + return TrafficPricing{ + PerTB: Price{ + Net: s.Traffic.PricePerTB.Net, // nolint:staticcheck // Field is deprecated, but we still need to map it as long as it is available + Gross: s.Traffic.PricePerTB.Gross, // nolint:staticcheck // Field is deprecated, but we still need to map it as long as it is available + Currency: s.Currency, + VATRate: s.VATRate, + }, + } +} + +func serverTypePricingFromSchema(s schema.Pricing) []ServerTypePricing { + p := make([]ServerTypePricing, len(s.ServerTypes)) + for i, serverType := range s.ServerTypes { + var pricings = make([]ServerTypeLocationPricing, len(serverType.Prices)) + for i, price := range serverType.Prices { + pricings[i] = ServerTypeLocationPricing{ + Location: &Location{Name: price.Location}, + Hourly: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PriceHourly.Net, + Gross: price.PriceHourly.Gross, + }, + Monthly: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PriceMonthly.Net, + Gross: price.PriceMonthly.Gross, + }, + IncludedTraffic: price.IncludedTraffic, + PerTBTraffic: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PricePerTBTraffic.Net, + Gross: price.PricePerTBTraffic.Gross, + }, + } + } + p[i] = ServerTypePricing{ + ServerType: &ServerType{ + ID: serverType.ID, + Name: serverType.Name, + }, + Pricings: pricings, + } + } + return p +} + +func loadBalancerTypePricingFromSchema(s schema.Pricing) []LoadBalancerTypePricing { + p := make([]LoadBalancerTypePricing, len(s.LoadBalancerTypes)) + for i, loadBalancerType := range s.LoadBalancerTypes { + var pricings = make([]LoadBalancerTypeLocationPricing, len(loadBalancerType.Prices)) + for i, price := range loadBalancerType.Prices { + pricings[i] = LoadBalancerTypeLocationPricing{ + Location: &Location{Name: price.Location}, + Hourly: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PriceHourly.Net, + Gross: price.PriceHourly.Gross, + }, + Monthly: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PriceMonthly.Net, + Gross: price.PriceMonthly.Gross, + }, + IncludedTraffic: price.IncludedTraffic, + PerTBTraffic: Price{ + Currency: s.Currency, + VATRate: s.VATRate, + Net: price.PricePerTBTraffic.Net, + Gross: price.PricePerTBTraffic.Gross, + }, + } + } + p[i] = LoadBalancerTypePricing{ + LoadBalancerType: &LoadBalancerType{ + ID: loadBalancerType.ID, + Name: loadBalancerType.Name, + }, + Pricings: pricings, + } + } + return p +} + +func volumePricingFromSchema(s schema.Pricing) VolumePricing { + return VolumePricing{ + PerGBMonthly: Price{ + Net: s.Volume.PricePerGBPerMonth.Net, + Gross: s.Volume.PricePerGBPerMonth.Gross, + Currency: s.Currency, + VATRate: s.VATRate, + }, + } +} + +func serverMetricsTimeSeriesFromSchema(s schema.ServerTimeSeriesVals) ([]ServerMetricsValue, error) { + vals := make([]ServerMetricsValue, len(s.Values)) + + for i, rawVal := range s.Values { + var val ServerMetricsValue + + tup, ok := rawVal.([]interface{}) + if !ok { + return nil, fmt.Errorf("failed to convert value to tuple: %v", rawVal) + } + if len(tup) != 2 { + return nil, fmt.Errorf("invalid tuple size: %d: %v", len(tup), rawVal) + } + ts, ok := tup[0].(float64) + if !ok { + return nil, fmt.Errorf("convert to float64: %v", tup[0]) + } + val.Timestamp = ts + + v, ok := tup[1].(string) + if !ok { + return nil, fmt.Errorf("not a string: %v", tup[1]) + } + val.Value = v + vals[i] = val + } + + return vals, nil +} + +func loadBalancerMetricsTimeSeriesFromSchema(s schema.LoadBalancerTimeSeriesVals) ([]LoadBalancerMetricsValue, error) { + vals := make([]LoadBalancerMetricsValue, len(s.Values)) + + for i, rawVal := range s.Values { + var val LoadBalancerMetricsValue + + tup, ok := rawVal.([]interface{}) + if !ok { + return nil, fmt.Errorf("failed to convert value to tuple: %v", rawVal) + } + if len(tup) != 2 { + return nil, fmt.Errorf("invalid tuple size: %d: %v", len(tup), rawVal) + } + ts, ok := tup[0].(float64) + if !ok { + return nil, fmt.Errorf("convert to float64: %v", tup[0]) + } + val.Timestamp = ts + + v, ok := tup[1].(string) + if !ok { + return nil, fmt.Errorf("not a string: %v", tup[1]) + } + val.Value = v + vals[i] = val + } + + return vals, nil +} + +func mapEmptyStringToNil(s string) *string { + if s == "" { + return nil + } + return &s +} + +func stringPtrFromLoadBalancerServiceProtocol(p LoadBalancerServiceProtocol) *string { + return mapEmptyStringToNil(string(p)) +} + +func stringPtrFromNetworkZone(z NetworkZone) *string { + return mapEmptyStringToNil(string(z)) +} + +func mapZeroInt64ToNil(i int64) *int64 { + if i == 0 { + return nil + } + return &i +} + +func mapZeroUint64ToNil(i uint64) *uint64 { + if i == 0 { + return nil + } + return &i +} + +func schemaFromLoadBalancerCreateOptsTargetLabelSelector(l LoadBalancerCreateOptsTargetLabelSelector) *schema.LoadBalancerCreateRequestTargetLabelSelector { + if l.Selector == "" { + return nil + } + return &schema.LoadBalancerCreateRequestTargetLabelSelector{Selector: l.Selector} +} + +func schemaFromLoadBalancerCreateOptsTargetIP(l LoadBalancerCreateOptsTargetIP) *schema.LoadBalancerCreateRequestTargetIP { + if l.IP == "" { + return nil + } + return &schema.LoadBalancerCreateRequestTargetIP{IP: l.IP} +} + +func schemaFromLoadBalancerCreateOptsTargetServer(l LoadBalancerCreateOptsTargetServer) *schema.LoadBalancerCreateRequestTargetServer { + if l.Server == nil { + return nil + } + return &schema.LoadBalancerCreateRequestTargetServer{ID: l.Server.ID} +} + +func stringMapToStringMapPtr(m map[string]string) *map[string]string { + if m == nil { + return nil + } + return &m +} + +func rawSchemaFromErrorDetails(v interface{}) json.RawMessage { + d := schemaFromErrorDetails(v) + if v == nil { + return nil + } + msg, err := json.Marshal(d) + if err != nil { + return nil + } + return msg +} + +func mapZeroFloat32ToNil(f float32) *float32 { + if f == 0 { + return nil + } + return &f +} + +func isDeprecationNotNil(d *DeprecationInfo) bool { + return d != nil +} + +// int64SlicePtrFromCertificatePtrSlice is needed so that a nil slice is mapped to nil instead of &nil. +func int64SlicePtrFromCertificatePtrSlice(s []*Certificate) *[]int64 { + if s == nil { + return nil + } + var ids = make([]int64, len(s)) + for i, cert := range s { + ids[i] = cert.ID + } + return &ids +} + +func stringSlicePtrFromStringSlice(s []string) *[]string { + if s == nil { + return nil + } + return &s +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/server.go similarity index 61% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/server.go index 894e9d73d8a45..fe9da9ec0fba5 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/server.go @@ -1,23 +1,20 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net" - "net/http" "net/url" "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Server represents a server in the Hetzner Cloud. type Server struct { - ID int + ID int64 Name string Status ServerStatus Created time.Time @@ -38,6 +35,7 @@ type Server struct { Volumes []*Volume PrimaryDiskSize int PlacementGroup *PlacementGroup + LoadBalancers []*LoadBalancer } // ServerProtection represents the protection level of a server. @@ -98,7 +96,7 @@ type ServerPublicNet struct { // ServerPublicNetIPv4 represents a server's public IPv4 address. type ServerPublicNetIPv4 struct { - ID int + ID int64 IP net.IP Blocked bool DNSPtr string @@ -110,7 +108,7 @@ func (n *ServerPublicNetIPv4) IsUnspecified() bool { // ServerPublicNetIPv6 represents a Server's public IPv6 network and address. type ServerPublicNetIPv6 struct { - ID int + ID int64 IP net.IP Network *net.IPNet Blocked bool @@ -154,26 +152,21 @@ const ( // changeDNSPtr changes or resets the reverse DNS pointer for a IP address. // Pass a nil ptr to reset the reverse DNS pointer to its default value. func (s *Server) changeDNSPtr(ctx context.Context, client *Client, ip net.IP, ptr *string) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/change_dns_ptr" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, s.ID) + reqBody := schema.ServerActionChangeDNSPtrRequest{ IP: ip.String(), DNSPtr: ptr, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/servers/%d/actions/change_dns_ptr", s.ID) - req, err := client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ServerActionChangeDNSPtrResponse{} - resp, err := client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionChangeDNSPtrResponse](ctx, client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -196,42 +189,34 @@ type ServerClient struct { } // GetByID retrieves a server by its ID. If the server does not exist, nil is returned. -func (c *ServerClient) GetByID(ctx context.Context, id int) (*Server, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/servers/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *ServerClient) GetByID(ctx context.Context, id int64) (*Server, *Response, error) { + const opPath = "/servers/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.ServerGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ServerGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return ServerFromSchema(body.Server), resp, nil + + return ServerFromSchema(respBody.Server), resp, nil } // GetByName retrieves a server by its name. If the server does not exist, nil is returned. func (c *ServerClient) GetByName(ctx context.Context, name string) (*Server, *Response, error) { - if name == "" { - return nil, nil, nil - } - servers, response, err := c.List(ctx, ServerListOpts{Name: name}) - if len(servers) == 0 { - return nil, response, err - } - return servers[0], response, err + return firstByName(name, func() ([]*Server, *Response, error) { + return c.List(ctx, ServerListOpts{Name: name}) + }) } // Get retrieves a server by its ID if the input can be parsed as an integer, otherwise it // retrieves a server by its name. If the server does not exist, nil is returned. func (c *ServerClient) Get(ctx context.Context, idOrName string) (*Server, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // ServerListOpts specifies options for listing servers. @@ -261,22 +246,17 @@ func (l ServerListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *ServerClient) List(ctx context.Context, opts ServerListOpts) ([]*Server, *Response, error) { - path := "/servers?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.ServerListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ServerListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - servers := make([]*Server, 0, len(body.Servers)) - for _, s := range body.Servers { - servers = append(servers, ServerFromSchema(s)) + return nil, resp, err } - return servers, resp, nil + + return allFromSchemaFunc(respBody.Servers, ServerFromSchema), resp, nil } // All returns all servers. @@ -286,22 +266,10 @@ func (c *ServerClient) All(ctx context.Context) ([]*Server, error) { // AllWithOpts returns all servers for the given options. func (c *ServerClient) AllWithOpts(ctx context.Context, opts ServerListOpts) ([]*Server, error) { - allServers := []*Server{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Server, *Response, error) { opts.Page = page - servers, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allServers = append(allServers, servers...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allServers, nil } // ServerCreateOpts specifies options for creating a new server. @@ -338,22 +306,16 @@ type ServerCreateFirewall struct { // Validate checks if options are valid. func (o ServerCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } if o.ServerType == nil || (o.ServerType.ID == 0 && o.ServerType.Name == "") { - return errors.New("missing server type") + return missingField(o, "ServerType") } if o.Image == nil || (o.Image.ID == 0 && o.Image.Name == "") { - return errors.New("missing image") + return missingField(o, "Image") } if o.Location != nil && o.Datacenter != nil { - return errors.New("location and datacenter are mutually exclusive") - } - if o.PublicNet != nil { - if !o.PublicNet.EnableIPv4 && !o.PublicNet.EnableIPv6 && - len(o.Networks) == 0 && (o.StartAfterCreate == nil || *o.StartAfterCreate) { - return errors.New("missing networks or StartAfterCreate == false when EnableIPv4 and EnableIPv6 is false") - } + return mutuallyExclusiveFields(o, "Location", "Datacenter") } return nil } @@ -368,8 +330,15 @@ type ServerCreateResult struct { // Create creates a new server. func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (ServerCreateResult, *Response, error) { + const opPath = "/servers" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := ServerCreateResult{} + + reqPath := opPath + if err := opts.Validate(); err != nil { - return ServerCreateResult{}, nil, err + return result, nil, err } var reqBody schema.ServerCreateRequest @@ -377,15 +346,11 @@ func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (Serve reqBody.Name = opts.Name reqBody.Automount = opts.Automount reqBody.StartAfterCreate = opts.StartAfterCreate - if opts.ServerType.ID != 0 { - reqBody.ServerType = opts.ServerType.ID - } else if opts.ServerType.Name != "" { - reqBody.ServerType = opts.ServerType.Name + if opts.ServerType.ID != 0 || opts.ServerType.Name != "" { + reqBody.ServerType = schema.IDOrName{ID: opts.ServerType.ID, Name: opts.ServerType.Name} } - if opts.Image.ID != 0 { - reqBody.Image = opts.Image.ID - } else if opts.Image.Name != "" { - reqBody.Image = opts.Image.Name + if opts.Image.ID != 0 || opts.Image.Name != "" { + reqBody.Image = schema.IDOrName{ID: opts.Image.ID, Name: opts.Image.Name} } if opts.Labels != nil { reqBody.Labels = &opts.Labels @@ -419,14 +384,14 @@ func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (Serve } if opts.Location != nil { if opts.Location.ID != 0 { - reqBody.Location = strconv.Itoa(opts.Location.ID) + reqBody.Location = strconv.FormatInt(opts.Location.ID, 10) } else { reqBody.Location = opts.Location.Name } } if opts.Datacenter != nil { if opts.Datacenter.ID != 0 { - reqBody.Datacenter = strconv.Itoa(opts.Datacenter.ID) + reqBody.Datacenter = strconv.FormatInt(opts.Datacenter.ID, 10) } else { reqBody.Datacenter = opts.Datacenter.Name } @@ -434,29 +399,19 @@ func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (Serve if opts.PlacementGroup != nil { reqBody.PlacementGroup = opts.PlacementGroup.ID } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return ServerCreateResult{}, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/servers", bytes.NewReader(reqBodyData)) + respBody, resp, err := postRequest[schema.ServerCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return ServerCreateResult{}, nil, err + return result, resp, err } - var respBody schema.ServerCreateResponse - resp, err := c.client.Do(req, &respBody) - if err != nil { - return ServerCreateResult{}, resp, err - } - result := ServerCreateResult{ - Server: ServerFromSchema(respBody.Server), - Action: ActionFromSchema(respBody.Action), - NextActions: ActionsFromSchema(respBody.NextActions), - } + result.Server = ServerFromSchema(respBody.Server) + result.Action = ActionFromSchema(respBody.Action) + result.NextActions = ActionsFromSchema(respBody.NextActions) if respBody.RootPassword != nil { result.RootPassword = *respBody.RootPassword } + return result, resp, nil } @@ -475,20 +430,21 @@ func (c *ServerClient) Delete(ctx context.Context, server *Server) (*Response, e // DeleteWithResult deletes a server and returns the parsed response containing the action. func (c *ServerClient) DeleteWithResult(ctx context.Context, server *Server) (*ServerDeleteResult, *Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/servers/%d", server.ID), nil) - if err != nil { - return &ServerDeleteResult{}, nil, err - } + const opPath = "/servers/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) - var respBody schema.ServerDeleteResponse - resp, err := c.client.Do(req, &respBody) + result := &ServerDeleteResult{} + + reqPath := fmt.Sprintf(opPath, server.ID) + + respBody, resp, err := deleteRequest[schema.ServerDeleteResponse](ctx, c.client, reqPath) if err != nil { - return &ServerDeleteResult{}, resp, err + return result, resp, err } - return &ServerDeleteResult{ - Action: ActionFromSchema(respBody.Action), - }, resp, nil + result.Action = ActionFromSchema(respBody.Action) + + return result, resp, nil } // ServerUpdateOpts specifies options for updating a server. @@ -499,108 +455,98 @@ type ServerUpdateOpts struct { // Update updates a server. func (c *ServerClient) Update(ctx context.Context, server *Server, opts ServerUpdateOpts) (*Server, *Response, error) { + const opPath = "/servers/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerUpdateRequest{ Name: opts.Name, } if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/servers/%d", server.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ServerUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.ServerUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ServerFromSchema(respBody.Server), resp, nil } // Poweron starts a server. func (c *ServerClient) Poweron(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/poweron", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/poweron" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionPoweronResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionPoweronResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // Reboot reboots a server. func (c *ServerClient) Reboot(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/reboot", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/reboot" + ctx = ctxutil.SetOpPath(ctx, opPath) - respBody := schema.ServerActionRebootResponse{} - resp, err := c.client.Do(req, &respBody) + reqPath := fmt.Sprintf(opPath, server.ID) + + respBody, resp, err := postRequest[schema.ServerActionRebootResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // Reset resets a server. func (c *ServerClient) Reset(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/reset", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/reset" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionResetResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionResetResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // Shutdown shuts down a server. func (c *ServerClient) Shutdown(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/shutdown", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/shutdown" + ctx = ctxutil.SetOpPath(ctx, opPath) - respBody := schema.ServerActionShutdownResponse{} - resp, err := c.client.Do(req, &respBody) + reqPath := fmt.Sprintf(opPath, server.ID) + + respBody, resp, err := postRequest[schema.ServerActionShutdownResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // Poweroff stops a server. func (c *ServerClient) Poweroff(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/poweroff", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/poweroff" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionPoweroffResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionPoweroffResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -612,21 +558,22 @@ type ServerResetPasswordResult struct { // ResetPassword resets a server's password. func (c *ServerClient) ResetPassword(ctx context.Context, server *Server) (ServerResetPasswordResult, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/reset_password", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return ServerResetPasswordResult{}, nil, err - } + const opPath = "/servers/%d/actions/reset_password" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := ServerResetPasswordResult{} - respBody := schema.ServerActionResetPasswordResponse{} - resp, err := c.client.Do(req, &respBody) + reqPath := fmt.Sprintf(opPath, server.ID) + + respBody, resp, err := postRequest[schema.ServerActionResetPasswordResponse](ctx, c.client, reqPath, nil) if err != nil { - return ServerResetPasswordResult{}, resp, err + return result, resp, err } - return ServerResetPasswordResult{ - Action: ActionFromSchema(respBody.Action), - RootPassword: respBody.RootPassword, - }, resp, nil + + result.Action = ActionFromSchema(respBody.Action) + result.RootPassword = respBody.RootPassword + + return result, resp, nil } // ServerCreateImageOpts specifies options for creating an image from a server. @@ -644,7 +591,7 @@ func (o ServerCreateImageOpts) Validate() error { case "": break default: - return errors.New("invalid type") + return invalidFieldValue(o, "Type", o.Type) } return nil @@ -658,10 +605,17 @@ type ServerCreateImageResult struct { // CreateImage creates an image from a server. func (c *ServerClient) CreateImage(ctx context.Context, server *Server, opts *ServerCreateImageOpts) (ServerCreateImageResult, *Response, error) { - var reqBody schema.ServerActionCreateImageRequest + const opPath = "/servers/%d/actions/create_image" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := ServerCreateImageResult{} + + reqPath := fmt.Sprintf(opPath, server.ID) + + reqBody := schema.ServerActionCreateImageRequest{} if opts != nil { if err := opts.Validate(); err != nil { - return ServerCreateImageResult{}, nil, fmt.Errorf("invalid options: %s", err) + return result, nil, err } if opts.Description != nil { reqBody.Description = opts.Description @@ -673,26 +627,16 @@ func (c *ServerClient) CreateImage(ctx context.Context, server *Server, opts *Se reqBody.Labels = &opts.Labels } } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return ServerCreateImageResult{}, nil, err - } - path := fmt.Sprintf("/servers/%d/actions/create_image", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) + respBody, resp, err := postRequest[schema.ServerActionCreateImageResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return ServerCreateImageResult{}, nil, err + return result, resp, err } - respBody := schema.ServerActionCreateImageResponse{} - resp, err := c.client.Do(req, &respBody) - if err != nil { - return ServerCreateImageResult{}, resp, err - } - return ServerCreateImageResult{ - Action: ActionFromSchema(respBody.Action), - Image: ImageFromSchema(respBody.Image), - }, resp, nil + result.Image = ImageFromSchema(respBody.Image) + result.Action = ActionFromSchema(respBody.Action) + + return result, resp, nil } // ServerEnableRescueOpts specifies options for enabling rescue mode for a server. @@ -709,48 +653,43 @@ type ServerEnableRescueResult struct { // EnableRescue enables rescue mode for a server. func (c *ServerClient) EnableRescue(ctx context.Context, server *Server, opts ServerEnableRescueOpts) (ServerEnableRescueResult, *Response, error) { + const opPath = "/servers/%d/actions/enable_rescue" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := ServerEnableRescueResult{} + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionEnableRescueRequest{ Type: Ptr(string(opts.Type)), } for _, sshKey := range opts.SSHKeys { reqBody.SSHKeys = append(reqBody.SSHKeys, sshKey.ID) } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return ServerEnableRescueResult{}, nil, err - } - path := fmt.Sprintf("/servers/%d/actions/enable_rescue", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) + respBody, resp, err := postRequest[schema.ServerActionEnableRescueResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return ServerEnableRescueResult{}, nil, err + return result, resp, err } - respBody := schema.ServerActionEnableRescueResponse{} - resp, err := c.client.Do(req, &respBody) - if err != nil { - return ServerEnableRescueResult{}, resp, err - } - result := ServerEnableRescueResult{ - Action: ActionFromSchema(respBody.Action), - RootPassword: respBody.RootPassword, - } + result.Action = ActionFromSchema(respBody.Action) + result.RootPassword = respBody.RootPassword + return result, resp, nil } // DisableRescue disables rescue mode for a server. func (c *ServerClient) DisableRescue(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/disable_rescue", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/disable_rescue" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionDisableRescueResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionDisableRescueResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -776,32 +715,24 @@ func (c *ServerClient) Rebuild(ctx context.Context, server *Server, opts ServerR // RebuildWithResult rebuilds a server. func (c *ServerClient) RebuildWithResult(ctx context.Context, server *Server, opts ServerRebuildOpts) (ServerRebuildResult, *Response, error) { - reqBody := schema.ServerActionRebuildRequest{} - if opts.Image.ID != 0 { - reqBody.Image = opts.Image.ID - } else { - reqBody.Image = opts.Image.Name - } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return ServerRebuildResult{}, nil, err - } + const opPath = "/servers/%d/actions/rebuild" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/servers/%d/actions/rebuild", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return ServerRebuildResult{}, nil, err + result := ServerRebuildResult{} + + reqPath := fmt.Sprintf(opPath, server.ID) + + reqBody := schema.ServerActionRebuildRequest{} + if opts.Image.ID != 0 || opts.Image.Name != "" { + reqBody.Image = schema.IDOrName{ID: opts.Image.ID, Name: opts.Image.Name} } - respBody := schema.ServerActionRebuildResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionRebuildResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return ServerRebuildResult{}, resp, err + return result, resp, err } - result := ServerRebuildResult{ - Action: ActionFromSchema(respBody.Action), - } + result.Action = ActionFromSchema(respBody.Action) if respBody.RootPassword != nil { result.RootPassword = *respBody.RootPassword } @@ -811,87 +742,69 @@ func (c *ServerClient) RebuildWithResult(ctx context.Context, server *Server, op // AttachISO attaches an ISO to a server. func (c *ServerClient) AttachISO(ctx context.Context, server *Server, iso *ISO) (*Action, *Response, error) { - reqBody := schema.ServerActionAttachISORequest{} - if iso.ID != 0 { - reqBody.ISO = iso.ID - } else { - reqBody.ISO = iso.Name - } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/attach_iso" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/servers/%d/actions/attach_iso", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err + reqPath := fmt.Sprintf(opPath, server.ID) + + reqBody := schema.ServerActionAttachISORequest{} + if iso.ID != 0 || iso.Name != "" { + reqBody.ISO = schema.IDOrName{ID: iso.ID, Name: iso.Name} } - respBody := schema.ServerActionAttachISOResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionAttachISOResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // DetachISO detaches the currently attached ISO from a server. func (c *ServerClient) DetachISO(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/detach_iso", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/detach_iso" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionDetachISOResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionDetachISOResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } -// EnableBackup enables backup for a server. Pass in an empty backup window to let the -// API pick a window for you. See the API documentation at docs.hetzner.cloud for a list -// of valid backup windows. +// EnableBackup enables backup for a server. +// The window parameter is deprecated and will be ignored. func (c *ServerClient) EnableBackup(ctx context.Context, server *Server, window string) (*Action, *Response, error) { - reqBody := schema.ServerActionEnableBackupRequest{} - if window != "" { - reqBody.BackupWindow = Ptr(window) - } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + _ = window - path := fmt.Sprintf("/servers/%d/actions/enable_backup", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/enable_backup" + ctx = ctxutil.SetOpPath(ctx, opPath) - respBody := schema.ServerActionEnableBackupResponse{} - resp, err := c.client.Do(req, &respBody) + reqPath := fmt.Sprintf(opPath, server.ID) + + respBody, resp, err := postRequest[schema.ServerActionEnableBackupResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } // DisableBackup disables backup for a server. func (c *ServerClient) DisableBackup(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/disable_backup", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/disable_backup" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionDisableBackupResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionDisableBackupResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -903,30 +816,23 @@ type ServerChangeTypeOpts struct { // ChangeType changes a server's type. func (c *ServerClient) ChangeType(ctx context.Context, server *Server, opts ServerChangeTypeOpts) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/change_type" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionChangeTypeRequest{ UpgradeDisk: opts.UpgradeDisk, } - if opts.ServerType.ID != 0 { - reqBody.ServerType = opts.ServerType.ID - } else { - reqBody.ServerType = opts.ServerType.Name - } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/servers/%d/actions/change_type", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err + if opts.ServerType.ID != 0 || opts.ServerType.Name != "" { + reqBody.ServerType = schema.IDOrName{ID: opts.ServerType.ID, Name: opts.ServerType.Name} } - respBody := schema.ServerActionChangeTypeResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionChangeTypeResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -948,27 +854,22 @@ type ServerChangeProtectionOpts struct { // ChangeProtection changes the resource protection level of a server. func (c *ServerClient) ChangeProtection(ctx context.Context, server *Server, opts ServerChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionChangeProtectionRequest{ Rebuild: opts.Rebuild, Delete: opts.Delete, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/servers/%d/actions/change_protection", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ServerActionChangeProtectionResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // ServerRequestConsoleResult is the result of requesting a WebSocket VNC console. @@ -980,22 +881,23 @@ type ServerRequestConsoleResult struct { // RequestConsole requests a WebSocket VNC console. func (c *ServerClient) RequestConsole(ctx context.Context, server *Server) (ServerRequestConsoleResult, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/request_console", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return ServerRequestConsoleResult{}, nil, err - } + const opPath = "/servers/%d/actions/request_console" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := ServerRequestConsoleResult{} - respBody := schema.ServerActionRequestConsoleResponse{} - resp, err := c.client.Do(req, &respBody) + reqPath := fmt.Sprintf(opPath, server.ID) + + respBody, resp, err := postRequest[schema.ServerActionRequestConsoleResponse](ctx, c.client, reqPath, nil) if err != nil { - return ServerRequestConsoleResult{}, resp, err + return result, resp, err } - return ServerRequestConsoleResult{ - Action: ActionFromSchema(respBody.Action), - WSSURL: respBody.WSSURL, - Password: respBody.Password, - }, resp, nil + + result.Action = ActionFromSchema(respBody.Action) + result.WSSURL = respBody.WSSURL + result.Password = respBody.Password + + return result, resp, nil } // ServerAttachToNetworkOpts specifies options for attaching a server to a network. @@ -1007,6 +909,11 @@ type ServerAttachToNetworkOpts struct { // AttachToNetwork attaches a server to a network. func (c *ServerClient) AttachToNetwork(ctx context.Context, server *Server, opts ServerAttachToNetworkOpts) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/attach_to_network" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionAttachToNetworkRequest{ Network: opts.Network.ID, } @@ -1016,22 +923,12 @@ func (c *ServerClient) AttachToNetwork(ctx context.Context, server *Server, opts for _, aliasIP := range opts.AliasIPs { reqBody.AliasIPs = append(reqBody.AliasIPs, Ptr(aliasIP.String())) } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/servers/%d/actions/attach_to_network", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.ServerActionAttachToNetworkResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionAttachToNetworkResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, err } @@ -1042,25 +939,20 @@ type ServerDetachFromNetworkOpts struct { // DetachFromNetwork detaches a server from a network. func (c *ServerClient) DetachFromNetwork(ctx context.Context, server *Server, opts ServerDetachFromNetworkOpts) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/detach_from_network" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionDetachFromNetworkRequest{ Network: opts.Network.ID, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/servers/%d/actions/detach_from_network", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ServerActionDetachFromNetworkResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionDetachFromNetworkResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, err } @@ -1072,6 +964,11 @@ type ServerChangeAliasIPsOpts struct { // ChangeAliasIPs changes a server's alias IPs in a network. func (c *ServerClient) ChangeAliasIPs(ctx context.Context, server *Server, opts ServerChangeAliasIPsOpts) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/change_alias_ips" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionChangeAliasIPsRequest{ Network: opts.Network.ID, AliasIPs: []string{}, @@ -1079,21 +976,12 @@ func (c *ServerClient) ChangeAliasIPs(ctx context.Context, server *Server, opts for _, aliasIP := range opts.AliasIPs { reqBody.AliasIPs = append(reqBody.AliasIPs, aliasIP.String()) } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/servers/%d/actions/change_alias_ips", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ServerActionDetachFromNetworkResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionChangeAliasIPsResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, err } @@ -1116,32 +1004,34 @@ type ServerGetMetricsOpts struct { Step int } -func (o *ServerGetMetricsOpts) addQueryParams(req *http.Request) error { - query := req.URL.Query() - +func (o ServerGetMetricsOpts) Validate() error { if len(o.Types) == 0 { - return fmt.Errorf("no metric types specified") + return missingField(o, "Types") + } + if o.Start.IsZero() { + return missingField(o, "Start") } + if o.End.IsZero() { + return missingField(o, "End") + } + return nil +} + +func (o ServerGetMetricsOpts) values() url.Values { + query := url.Values{} + for _, typ := range o.Types { query.Add("type", string(typ)) } - if o.Start.IsZero() { - return fmt.Errorf("no start time specified") - } query.Add("start", o.Start.Format(time.RFC3339)) - - if o.End.IsZero() { - return fmt.Errorf("no end time specified") - } query.Add("end", o.End.Format(time.RFC3339)) if o.Step > 0 { query.Add("step", strconv.Itoa(o.Step)) } - req.URL.RawQuery = query.Encode() - return nil + return query } // ServerMetrics contains the metrics requested for a Server. @@ -1160,64 +1050,60 @@ type ServerMetricsValue struct { // GetMetrics obtains metrics for Server. func (c *ServerClient) GetMetrics(ctx context.Context, server *Server, opts ServerGetMetricsOpts) (*ServerMetrics, *Response, error) { - var respBody schema.ServerGetMetricsResponse + const opPath = "/servers/%d/metrics?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) if server == nil { - return nil, nil, fmt.Errorf("illegal argument: server is nil") + return nil, nil, missingArgument("server", server) } - path := fmt.Sprintf("/servers/%d/metrics", server.ID) - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, fmt.Errorf("new request: %v", err) - } - if err := opts.addQueryParams(req); err != nil { - return nil, nil, fmt.Errorf("add query params: %v", err) + if err := opts.Validate(); err != nil { + return nil, nil, err } - resp, err := c.client.Do(req, &respBody) + + reqPath := fmt.Sprintf(opPath, server.ID, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.ServerGetMetricsResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, fmt.Errorf("get metrics: %v", err) + return nil, resp, err } - ms, err := serverMetricsFromSchema(&respBody) + + metrics, err := serverMetricsFromSchema(&respBody) if err != nil { - return nil, nil, fmt.Errorf("convert response body: %v", err) + return nil, nil, fmt.Errorf("convert response body: %w", err) } - return ms, resp, nil + + return metrics, resp, nil } func (c *ServerClient) AddToPlacementGroup(ctx context.Context, server *Server, placementGroup *PlacementGroup) (*Action, *Response, error) { + const opPath = "/servers/%d/actions/add_to_placement_group" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) + reqBody := schema.ServerActionAddToPlacementGroupRequest{ PlacementGroup: placementGroup.ID, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/servers/%d/actions/add_to_placement_group", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.ServerActionAddToPlacementGroupResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionAddToPlacementGroupResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } func (c *ServerClient) RemoveFromPlacementGroup(ctx context.Context, server *Server) (*Action, *Response, error) { - path := fmt.Sprintf("/servers/%d/actions/remove_from_placement_group", server.ID) - req, err := c.client.NewRequest(ctx, "POST", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/servers/%d/actions/remove_from_placement_group" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, server.ID) - respBody := schema.ServerActionRemoveFromPlacementGroupResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.ServerActionRemoveFromPlacementGroupResponse](ctx, c.client, reqPath, nil) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/server_type.go similarity index 66% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/server_type.go index 7f8e09ecd2b57..f3ffca26a3bed 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/server_type.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/server_type.go @@ -6,12 +6,13 @@ import ( "net/url" "strconv" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // ServerType represents a server type in the Hetzner Cloud. type ServerType struct { - ID int + ID int64 Name string Description string Cores int @@ -56,40 +57,35 @@ type ServerTypeClient struct { } // GetByID retrieves a server type by its ID. If the server type does not exist, nil is returned. -func (c *ServerTypeClient) GetByID(ctx context.Context, id int) (*ServerType, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/server_types/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *ServerTypeClient) GetByID(ctx context.Context, id int64) (*ServerType, *Response, error) { + const opPath = "/server_types/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.ServerTypeGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.ServerTypeGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return ServerTypeFromSchema(body.ServerType), resp, nil + + return ServerTypeFromSchema(respBody.ServerType), resp, nil } // GetByName retrieves a server type by its name. If the server type does not exist, nil is returned. func (c *ServerTypeClient) GetByName(ctx context.Context, name string) (*ServerType, *Response, error) { - if name == "" { - return nil, nil, nil - } - serverTypes, response, err := c.List(ctx, ServerTypeListOpts{Name: name}) - if len(serverTypes) == 0 { - return nil, response, err - } - return serverTypes[0], response, err + return firstByName(name, func() ([]*ServerType, *Response, error) { + return c.List(ctx, ServerTypeListOpts{Name: name}) + }) } // Get retrieves a server type by its ID if the input can be parsed as an integer, otherwise it // retrieves a server type by its name. If the server type does not exist, nil is returned. func (c *ServerTypeClient) Get(ctx context.Context, idOrName string) (*ServerType, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) + if id, err := strconv.ParseInt(idOrName, 10, 64); err == nil { + return c.GetByID(ctx, id) } return c.GetByName(ctx, idOrName) } @@ -117,22 +113,17 @@ func (l ServerTypeListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *ServerTypeClient) List(ctx context.Context, opts ServerTypeListOpts) ([]*ServerType, *Response, error) { - path := "/server_types?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/server_types?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.ServerTypeListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.ServerTypeListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - serverTypes := make([]*ServerType, 0, len(body.ServerTypes)) - for _, s := range body.ServerTypes { - serverTypes = append(serverTypes, ServerTypeFromSchema(s)) + return nil, resp, err } - return serverTypes, resp, nil + + return allFromSchemaFunc(respBody.ServerTypes, ServerTypeFromSchema), resp, nil } // All returns all server types. @@ -142,20 +133,8 @@ func (c *ServerTypeClient) All(ctx context.Context) ([]*ServerType, error) { // AllWithOpts returns all server types for the given options. func (c *ServerTypeClient) AllWithOpts(ctx context.Context, opts ServerTypeListOpts) ([]*ServerType, error) { - allServerTypes := []*ServerType{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*ServerType, *Response, error) { opts.Page = page - serverTypes, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allServerTypes = append(allServerTypes, serverTypes...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allServerTypes, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/ssh_key.go similarity index 59% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/ssh_key.go index cdf9651561d0b..7b1e8cc200458 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/ssh_key.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/ssh_key.go @@ -1,21 +1,18 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // SSHKey represents a SSH key in the Hetzner Cloud. type SSHKey struct { - ID int + ID int64 Name string Fingerprint string PublicKey string @@ -29,51 +26,41 @@ type SSHKeyClient struct { } // GetByID retrieves a SSH key by its ID. If the SSH key does not exist, nil is returned. -func (c *SSHKeyClient) GetByID(ctx context.Context, id int) (*SSHKey, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/ssh_keys/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *SSHKeyClient) GetByID(ctx context.Context, id int64) (*SSHKey, *Response, error) { + const opPath = "/ssh_keys/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.SSHKeyGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.SSHKeyGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return SSHKeyFromSchema(body.SSHKey), resp, nil + + return SSHKeyFromSchema(respBody.SSHKey), resp, nil } // GetByName retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) GetByName(ctx context.Context, name string) (*SSHKey, *Response, error) { - if name == "" { - return nil, nil, nil - } - sshKeys, response, err := c.List(ctx, SSHKeyListOpts{Name: name}) - if len(sshKeys) == 0 { - return nil, response, err - } - return sshKeys[0], response, err + return firstByName(name, func() ([]*SSHKey, *Response, error) { + return c.List(ctx, SSHKeyListOpts{Name: name}) + }) } // GetByFingerprint retreives a SSH key by its fingerprint. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) GetByFingerprint(ctx context.Context, fingerprint string) (*SSHKey, *Response, error) { - sshKeys, response, err := c.List(ctx, SSHKeyListOpts{Fingerprint: fingerprint}) - if len(sshKeys) == 0 { - return nil, response, err - } - return sshKeys[0], response, err + return firstBy(func() ([]*SSHKey, *Response, error) { + return c.List(ctx, SSHKeyListOpts{Fingerprint: fingerprint}) + }) } // Get retrieves a SSH key by its ID if the input can be parsed as an integer, otherwise it // retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. func (c *SSHKeyClient) Get(ctx context.Context, idOrName string) (*SSHKey, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // SSHKeyListOpts specifies options for listing SSH keys. @@ -103,22 +90,17 @@ func (l SSHKeyListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *SSHKeyClient) List(ctx context.Context, opts SSHKeyListOpts) ([]*SSHKey, *Response, error) { - path := "/ssh_keys?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/ssh_keys?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) - var body schema.SSHKeyListResponse - resp, err := c.client.Do(req, &body) + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) + + respBody, resp, err := getRequest[schema.SSHKeyListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - sshKeys := make([]*SSHKey, 0, len(body.SSHKeys)) - for _, s := range body.SSHKeys { - sshKeys = append(sshKeys, SSHKeyFromSchema(s)) + return nil, resp, err } - return sshKeys, resp, nil + + return allFromSchemaFunc(respBody.SSHKeys, SSHKeyFromSchema), resp, nil } // All returns all SSH keys. @@ -128,22 +110,10 @@ func (c *SSHKeyClient) All(ctx context.Context) ([]*SSHKey, error) { // AllWithOpts returns all SSH keys with the given options. func (c *SSHKeyClient) AllWithOpts(ctx context.Context, opts SSHKeyListOpts) ([]*SSHKey, error) { - allSSHKeys := []*SSHKey{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*SSHKey, *Response, error) { opts.Page = page - sshKeys, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allSSHKeys = append(allSSHKeys, sshKeys...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allSSHKeys, nil } // SSHKeyCreateOpts specifies parameters for creating a SSH key. @@ -156,16 +126,21 @@ type SSHKeyCreateOpts struct { // Validate checks if options are valid. func (o SSHKeyCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } if o.PublicKey == "" { - return errors.New("missing public key") + return missingField(o, "PublicKey") } return nil } // Create creates a new SSH key with the given options. func (c *SSHKeyClient) Create(ctx context.Context, opts SSHKeyCreateOpts) (*SSHKey, *Response, error) { + const opPath = "/ssh_keys" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := opPath + if err := opts.Validate(); err != nil { return nil, nil, err } @@ -176,31 +151,23 @@ func (c *SSHKeyClient) Create(ctx context.Context, opts SSHKeyCreateOpts) (*SSHK if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - req, err := c.client.NewRequest(ctx, "POST", "/ssh_keys", bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.SSHKeyCreateResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.SSHKeyCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return SSHKeyFromSchema(respBody.SSHKey), resp, nil } // Delete deletes a SSH key. func (c *SSHKeyClient) Delete(ctx context.Context, sshKey *SSHKey) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/ssh_keys/%d", sshKey.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/ssh_keys/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, sshKey.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // SSHKeyUpdateOpts specifies options for updating a SSH key. @@ -211,27 +178,22 @@ type SSHKeyUpdateOpts struct { // Update updates a SSH key. func (c *SSHKeyClient) Update(ctx context.Context, sshKey *SSHKey, opts SSHKeyUpdateOpts) (*SSHKey, *Response, error) { + const opPath = "/ssh_keys/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, sshKey.ID) + reqBody := schema.SSHKeyUpdateRequest{ Name: opts.Name, } if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/ssh_keys/%d", sshKey.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - respBody := schema.SSHKeyUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.SSHKeyUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return SSHKeyFromSchema(respBody.SSHKey), resp, nil } diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/testing.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/testing.go similarity index 100% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/testing.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/testing.go diff --git a/vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/volume.go similarity index 58% rename from vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go rename to vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/volume.go index 747c17de5cc54..b606eba2de546 100644 --- a/vendor/github.com/hetznercloud/hcloud-go/hcloud/volume.go +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/volume.go @@ -1,21 +1,18 @@ package hcloud import ( - "bytes" "context" - "encoding/json" - "errors" "fmt" "net/url" - "strconv" "time" - "github.com/hetznercloud/hcloud-go/hcloud/schema" + "github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil" + "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" ) // Volume represents a volume in the Hetzner Cloud. type Volume struct { - ID int + ID int64 Name string Status VolumeStatus Server *Server @@ -56,42 +53,34 @@ const ( ) // GetByID retrieves a volume by its ID. If the volume does not exist, nil is returned. -func (c *VolumeClient) GetByID(ctx context.Context, id int) (*Volume, *Response, error) { - req, err := c.client.NewRequest(ctx, "GET", fmt.Sprintf("/volumes/%d", id), nil) - if err != nil { - return nil, nil, err - } +func (c *VolumeClient) GetByID(ctx context.Context, id int64) (*Volume, *Response, error) { + const opPath = "/volumes/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, id) - var body schema.VolumeGetResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.VolumeGetResponse](ctx, c.client, reqPath) if err != nil { if IsError(err, ErrorCodeNotFound) { return nil, resp, nil } - return nil, nil, err + return nil, resp, err } - return VolumeFromSchema(body.Volume), resp, nil + + return VolumeFromSchema(respBody.Volume), resp, nil } // GetByName retrieves a volume by its name. If the volume does not exist, nil is returned. func (c *VolumeClient) GetByName(ctx context.Context, name string) (*Volume, *Response, error) { - if name == "" { - return nil, nil, nil - } - volumes, response, err := c.List(ctx, VolumeListOpts{Name: name}) - if len(volumes) == 0 { - return nil, response, err - } - return volumes[0], response, err + return firstByName(name, func() ([]*Volume, *Response, error) { + return c.List(ctx, VolumeListOpts{Name: name}) + }) } // Get retrieves a volume by its ID if the input can be parsed as an integer, otherwise it // retrieves a volume by its name. If the volume does not exist, nil is returned. func (c *VolumeClient) Get(ctx context.Context, idOrName string) (*Volume, *Response, error) { - if id, err := strconv.Atoi(idOrName); err == nil { - return c.GetByID(ctx, int(id)) - } - return c.GetByName(ctx, idOrName) + return getByIDOrName(ctx, c.GetByID, c.GetByName, idOrName) } // VolumeListOpts specifies options for listing volumes. @@ -121,22 +110,17 @@ func (l VolumeListOpts) values() url.Values { // Please note that filters specified in opts are not taken into account // when their value corresponds to their zero value or when they are empty. func (c *VolumeClient) List(ctx context.Context, opts VolumeListOpts) ([]*Volume, *Response, error) { - path := "/volumes?" + opts.values().Encode() - req, err := c.client.NewRequest(ctx, "GET", path, nil) - if err != nil { - return nil, nil, err - } + const opPath = "/volumes?%s" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, opts.values().Encode()) - var body schema.VolumeListResponse - resp, err := c.client.Do(req, &body) + respBody, resp, err := getRequest[schema.VolumeListResponse](ctx, c.client, reqPath) if err != nil { - return nil, nil, err - } - volumes := make([]*Volume, 0, len(body.Volumes)) - for _, s := range body.Volumes { - volumes = append(volumes, VolumeFromSchema(s)) + return nil, resp, err } - return volumes, resp, nil + + return allFromSchemaFunc(respBody.Volumes, VolumeFromSchema), resp, nil } // All returns all volumes. @@ -146,22 +130,10 @@ func (c *VolumeClient) All(ctx context.Context) ([]*Volume, error) { // AllWithOpts returns all volumes with the given options. func (c *VolumeClient) AllWithOpts(ctx context.Context, opts VolumeListOpts) ([]*Volume, error) { - allVolumes := []*Volume{} - - err := c.client.all(func(page int) (*Response, error) { + return iterPages(func(page int) ([]*Volume, *Response, error) { opts.Page = page - volumes, resp, err := c.List(ctx, opts) - if err != nil { - return resp, err - } - allVolumes = append(allVolumes, volumes...) - return resp, nil + return c.List(ctx, opts) }) - if err != nil { - return nil, err - } - - return allVolumes, nil } // VolumeCreateOpts specifies parameters for creating a volume. @@ -178,19 +150,19 @@ type VolumeCreateOpts struct { // Validate checks if options are valid. func (o VolumeCreateOpts) Validate() error { if o.Name == "" { - return errors.New("missing name") + return missingField(o, "Name") } if o.Size <= 0 { - return errors.New("size must be greater than 0") + return invalidFieldValue(o, "Size", o.Size) } if o.Server == nil && o.Location == nil { - return errors.New("one of server or location must be provided") + return missingOneOfFields(o, "Server", "Location") } if o.Server != nil && o.Location != nil { - return errors.New("only one of server or location must be provided") + return mutuallyExclusiveFields(o, "Server", "Location") } if o.Server == nil && (o.Automount != nil && *o.Automount) { - return errors.New("server must be provided when automount is true") + return missingRequiredTogetherFields(o, "Automount", "Server") } return nil } @@ -204,8 +176,15 @@ type VolumeCreateResult struct { // Create creates a new volume with the given options. func (c *VolumeClient) Create(ctx context.Context, opts VolumeCreateOpts) (VolumeCreateResult, *Response, error) { + const opPath = "/volumes" + ctx = ctxutil.SetOpPath(ctx, opPath) + + result := VolumeCreateResult{} + + reqPath := opPath + if err := opts.Validate(); err != nil { - return VolumeCreateResult{}, nil, err + return result, nil, err } reqBody := schema.VolumeCreateRequest{ Name: opts.Name, @@ -220,48 +199,33 @@ func (c *VolumeClient) Create(ctx context.Context, opts VolumeCreateOpts) (Volum reqBody.Server = Ptr(opts.Server.ID) } if opts.Location != nil { - if opts.Location.ID != 0 { - reqBody.Location = opts.Location.ID - } else { - reqBody.Location = opts.Location.Name + if opts.Location.ID != 0 || opts.Location.Name != "" { + reqBody.Location = &schema.IDOrName{ID: opts.Location.ID, Name: opts.Location.Name} } } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return VolumeCreateResult{}, nil, err - } - - req, err := c.client.NewRequest(ctx, "POST", "/volumes", bytes.NewReader(reqBodyData)) - if err != nil { - return VolumeCreateResult{}, nil, err - } - - var respBody schema.VolumeCreateResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.VolumeCreateResponse](ctx, c.client, reqPath, reqBody) if err != nil { - return VolumeCreateResult{}, resp, err + return result, resp, err } - var action *Action + result.Volume = VolumeFromSchema(respBody.Volume) if respBody.Action != nil { - action = ActionFromSchema(*respBody.Action) + result.Action = ActionFromSchema(*respBody.Action) } + result.NextActions = ActionsFromSchema(respBody.NextActions) - return VolumeCreateResult{ - Volume: VolumeFromSchema(respBody.Volume), - Action: action, - NextActions: ActionsFromSchema(respBody.NextActions), - }, resp, nil + return result, resp, nil } // Delete deletes a volume. func (c *VolumeClient) Delete(ctx context.Context, volume *Volume) (*Response, error) { - req, err := c.client.NewRequest(ctx, "DELETE", fmt.Sprintf("/volumes/%d", volume.ID), nil) - if err != nil { - return nil, err - } - return c.client.Do(req, nil) + const opPath = "/volumes/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, volume.ID) + + return deleteRequestNoResult(ctx, c.client, reqPath) } // VolumeUpdateOpts specifies options for updating a volume. @@ -272,28 +236,23 @@ type VolumeUpdateOpts struct { // Update updates a volume. func (c *VolumeClient) Update(ctx context.Context, volume *Volume, opts VolumeUpdateOpts) (*Volume, *Response, error) { + const opPath = "/volumes/%d" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, volume.ID) + reqBody := schema.VolumeUpdateRequest{ Name: opts.Name, } if opts.Labels != nil { reqBody.Labels = &opts.Labels } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/volumes/%d", volume.ID) - req, err := c.client.NewRequest(ctx, "PUT", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.VolumeUpdateResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := putRequest[schema.VolumeUpdateResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return VolumeFromSchema(respBody.Volume), resp, nil } @@ -305,27 +264,21 @@ type VolumeAttachOpts struct { // AttachWithOpts attaches a volume to a server. func (c *VolumeClient) AttachWithOpts(ctx context.Context, volume *Volume, opts VolumeAttachOpts) (*Action, *Response, error) { + const opPath = "/volumes/%d/actions/attach" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, volume.ID) + reqBody := schema.VolumeActionAttachVolumeRequest{ Server: opts.Server.ID, Automount: opts.Automount, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - - path := fmt.Sprintf("/volumes/%d/actions/attach", volume.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - var respBody schema.VolumeActionAttachVolumeResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.VolumeActionAttachVolumeResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -336,23 +289,18 @@ func (c *VolumeClient) Attach(ctx context.Context, volume *Volume, server *Serve // Detach detaches a volume from a server. func (c *VolumeClient) Detach(ctx context.Context, volume *Volume) (*Action, *Response, error) { - var reqBody schema.VolumeActionDetachVolumeRequest - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } + const opPath = "/volumes/%d/actions/detach" + ctx = ctxutil.SetOpPath(ctx, opPath) - path := fmt.Sprintf("/volumes/%d/actions/detach", volume.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } + reqPath := fmt.Sprintf(opPath, volume.ID) + + var reqBody schema.VolumeActionDetachVolumeRequest - var respBody schema.VolumeActionDetachVolumeResponse - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.VolumeActionDetachVolumeResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, nil } @@ -363,48 +311,38 @@ type VolumeChangeProtectionOpts struct { // ChangeProtection changes the resource protection level of a volume. func (c *VolumeClient) ChangeProtection(ctx context.Context, volume *Volume, opts VolumeChangeProtectionOpts) (*Action, *Response, error) { + const opPath = "/volumes/%d/actions/change_protection" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, volume.ID) + reqBody := schema.VolumeActionChangeProtectionRequest{ Delete: opts.Delete, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/volumes/%d/actions/change_protection", volume.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.VolumeActionChangeProtectionResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.VolumeActionChangeProtectionResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } - return ActionFromSchema(respBody.Action), resp, err + + return ActionFromSchema(respBody.Action), resp, nil } // Resize changes the size of a volume. func (c *VolumeClient) Resize(ctx context.Context, volume *Volume, size int) (*Action, *Response, error) { + const opPath = "/volumes/%d/actions/resize" + ctx = ctxutil.SetOpPath(ctx, opPath) + + reqPath := fmt.Sprintf(opPath, volume.ID) + reqBody := schema.VolumeActionResizeVolumeRequest{ Size: size, } - reqBodyData, err := json.Marshal(reqBody) - if err != nil { - return nil, nil, err - } - path := fmt.Sprintf("/volumes/%d/actions/resize", volume.ID) - req, err := c.client.NewRequest(ctx, "POST", path, bytes.NewReader(reqBodyData)) - if err != nil { - return nil, nil, err - } - - respBody := schema.VolumeActionResizeVolumeResponse{} - resp, err := c.client.Do(req, &respBody) + respBody, resp, err := postRequest[schema.VolumeActionResizeVolumeResponse](ctx, c.client, reqPath, reqBody) if err != nil { return nil, resp, err } + return ActionFromSchema(respBody.Action), resp, err } diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_action_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_action_client_iface.go new file mode 100644 index 0000000000000..ec4d3bfb097d2 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_action_client_iface.go @@ -0,0 +1,83 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IActionClient ... +type IActionClient interface { + // GetByID retrieves an action by its ID. If the action does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Action, *Response, error) + // List returns a list of actions for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts ActionListOpts) ([]*Action, *Response, error) + // All returns all actions. + // + // Deprecated: It is required to pass in a list of IDs since 30 January 2025. Please use [ActionClient.AllWithOpts] instead. + All(ctx context.Context) ([]*Action, error) + // AllWithOpts returns all actions for the given options. + // + // It is required to set [ActionListOpts.ID]. Any other fields set in the opts are ignored. + AllWithOpts(ctx context.Context, opts ActionListOpts) ([]*Action, error) + // WatchOverallProgress watches several actions' progress until they complete + // with success or error. This watching happens in a goroutine and updates are + // provided through the two returned channels: + // + // - The first channel receives percentage updates of the progress, based on + // the number of completed versus total watched actions. The return value + // is an int between 0 and 100. + // - The second channel returned receives errors for actions that did not + // complete successfully, as well as any errors that happened while + // querying the API. + // + // By default, the method keeps watching until all actions have finished + // processing. If you want to be able to cancel the method or configure a + // timeout, use the [context.Context]. Once the method has stopped watching, + // both returned channels are closed. + // + // WatchOverallProgress uses the [WithPollOpts] of the [Client] to wait + // until sending the next request. + // + // Deprecated: WatchOverallProgress is deprecated, use [WaitForFunc] instead. + WatchOverallProgress(ctx context.Context, actions []*Action) (<-chan int, <-chan error) + // WatchProgress watches one action's progress until it completes with success + // or error. This watching happens in a goroutine and updates are provided + // through the two returned channels: + // + // - The first channel receives percentage updates of the progress, based on + // the progress percentage indicated by the API. The return value is an int + // between 0 and 100. + // - The second channel receives any errors that happened while querying the + // API, as well as the error of the action if it did not complete + // successfully, or nil if it did. + // + // By default, the method keeps watching until the action has finished + // processing. If you want to be able to cancel the method or configure a + // timeout, use the [context.Context]. Once the method has stopped watching, + // both returned channels are closed. + // + // WatchProgress uses the [WithPollOpts] of the [Client] to wait until + // sending the next request. + // + // Deprecated: WatchProgress is deprecated, use [WaitForFunc] instead. + WatchProgress(ctx context.Context, action *Action) (<-chan int, <-chan error) + // WaitForFunc waits until all actions are completed by polling the API at the interval + // defined by [WithPollOpts]. An action is considered as complete when its status is + // either [ActionStatusSuccess] or [ActionStatusError]. + // + // The handleUpdate callback is called every time an action is updated. + WaitForFunc(ctx context.Context, handleUpdate func(update *Action) error, actions ...*Action) error + // WaitFor waits until all actions succeed by polling the API at the interval defined by + // [WithPollOpts]. An action is considered as succeeded when its status is either + // [ActionStatusSuccess]. + // + // If a single action fails, the function will stop waiting and the error set in the + // action will be returned as an [ActionError]. + // + // For more flexibility, see the [ActionClient.WaitForFunc] function. + WaitFor(ctx context.Context, actions ...*Action) error +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_certificate_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_certificate_client_iface.go new file mode 100644 index 0000000000000..94583925ff560 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_certificate_client_iface.go @@ -0,0 +1,40 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// ICertificateClient ... +type ICertificateClient interface { + // GetByID retrieves a Certificate by its ID. If the Certificate does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Certificate, *Response, error) + // GetByName retrieves a Certificate by its name. If the Certificate does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Certificate, *Response, error) + // Get retrieves a Certificate by its ID if the input can be parsed as an integer, otherwise it + // retrieves a Certificate by its name. If the Certificate does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Certificate, *Response, error) + // List returns a list of Certificates for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts CertificateListOpts) ([]*Certificate, *Response, error) + // All returns all Certificates. + All(ctx context.Context) ([]*Certificate, error) + // AllWithOpts returns all Certificates for the given options. + AllWithOpts(ctx context.Context, opts CertificateListOpts) ([]*Certificate, error) + // Create creates a new uploaded certificate. + // + // Create returns an error for certificates of any other type. Use + // CreateCertificate to create such certificates. + Create(ctx context.Context, opts CertificateCreateOpts) (*Certificate, *Response, error) + // CreateCertificate creates a new certificate of any type. + CreateCertificate(ctx context.Context, opts CertificateCreateOpts) (CertificateCreateResult, *Response, error) + // Update updates a Certificate. + Update(ctx context.Context, certificate *Certificate, opts CertificateUpdateOpts) (*Certificate, *Response, error) + // Delete deletes a certificate. + Delete(ctx context.Context, certificate *Certificate) (*Response, error) + // RetryIssuance retries the issuance of a failed managed certificate. + RetryIssuance(ctx context.Context, certificate *Certificate) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_datacenter_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_datacenter_client_iface.go new file mode 100644 index 0000000000000..f937675678359 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_datacenter_client_iface.go @@ -0,0 +1,27 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IDatacenterClient ... +type IDatacenterClient interface { + // GetByID retrieves a datacenter by its ID. If the datacenter does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Datacenter, *Response, error) + // GetByName retrieves a datacenter by its name. If the datacenter does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Datacenter, *Response, error) + // Get retrieves a datacenter by its ID if the input can be parsed as an integer, otherwise it + // retrieves a datacenter by its name. If the datacenter does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Datacenter, *Response, error) + // List returns a list of datacenters for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts DatacenterListOpts) ([]*Datacenter, *Response, error) + // All returns all datacenters. + All(ctx context.Context) ([]*Datacenter, error) + // AllWithOpts returns all datacenters for the given options. + AllWithOpts(ctx context.Context, opts DatacenterListOpts) ([]*Datacenter, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_firewall_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_firewall_client_iface.go new file mode 100644 index 0000000000000..ce6481158b512 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_firewall_client_iface.go @@ -0,0 +1,37 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IFirewallClient ... +type IFirewallClient interface { + // GetByID retrieves a Firewall by its ID. If the Firewall does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Firewall, *Response, error) + // GetByName retrieves a Firewall by its name. If the Firewall does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Firewall, *Response, error) + // Get retrieves a Firewall by its ID if the input can be parsed as an integer, otherwise it + // retrieves a Firewall by its name. If the Firewall does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Firewall, *Response, error) + // List returns a list of Firewalls for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts FirewallListOpts) ([]*Firewall, *Response, error) + // All returns all Firewalls. + All(ctx context.Context) ([]*Firewall, error) + // AllWithOpts returns all Firewalls for the given options. + AllWithOpts(ctx context.Context, opts FirewallListOpts) ([]*Firewall, error) + // Create creates a new Firewall. + Create(ctx context.Context, opts FirewallCreateOpts) (FirewallCreateResult, *Response, error) + // Update updates a Firewall. + Update(ctx context.Context, firewall *Firewall, opts FirewallUpdateOpts) (*Firewall, *Response, error) + // Delete deletes a Firewall. + Delete(ctx context.Context, firewall *Firewall) (*Response, error) + // SetRules sets the rules of a Firewall. + SetRules(ctx context.Context, firewall *Firewall, opts FirewallSetRulesOpts) ([]*Action, *Response, error) + ApplyResources(ctx context.Context, firewall *Firewall, resources []FirewallResource) ([]*Action, *Response, error) + RemoveResources(ctx context.Context, firewall *Firewall, resources []FirewallResource) ([]*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_floating_ip_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_floating_ip_client_iface.go new file mode 100644 index 0000000000000..4d71be2690681 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_floating_ip_client_iface.go @@ -0,0 +1,43 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IFloatingIPClient ... +type IFloatingIPClient interface { + // GetByID retrieves a Floating IP by its ID. If the Floating IP does not exist, + // nil is returned. + GetByID(ctx context.Context, id int64) (*FloatingIP, *Response, error) + // GetByName retrieves a Floating IP by its name. If the Floating IP does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*FloatingIP, *Response, error) + // Get retrieves a Floating IP by its ID if the input can be parsed as an integer, otherwise it + // retrieves a Floating IP by its name. If the Floating IP does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*FloatingIP, *Response, error) + // List returns a list of Floating IPs for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts FloatingIPListOpts) ([]*FloatingIP, *Response, error) + // All returns all Floating IPs. + All(ctx context.Context) ([]*FloatingIP, error) + // AllWithOpts returns all Floating IPs for the given options. + AllWithOpts(ctx context.Context, opts FloatingIPListOpts) ([]*FloatingIP, error) + // Create creates a Floating IP. + Create(ctx context.Context, opts FloatingIPCreateOpts) (FloatingIPCreateResult, *Response, error) + // Delete deletes a Floating IP. + Delete(ctx context.Context, floatingIP *FloatingIP) (*Response, error) + // Update updates a Floating IP. + Update(ctx context.Context, floatingIP *FloatingIP, opts FloatingIPUpdateOpts) (*FloatingIP, *Response, error) + // Assign assigns a Floating IP to a server. + Assign(ctx context.Context, floatingIP *FloatingIP, server *Server) (*Action, *Response, error) + // Unassign unassigns a Floating IP from the currently assigned server. + Unassign(ctx context.Context, floatingIP *FloatingIP) (*Action, *Response, error) + // ChangeDNSPtr changes or resets the reverse DNS pointer for a Floating IP address. + // Pass a nil ptr to reset the reverse DNS pointer to its default value. + ChangeDNSPtr(ctx context.Context, floatingIP *FloatingIP, ip string, ptr *string) (*Action, *Response, error) + // ChangeProtection changes the resource protection level of a Floating IP. + ChangeProtection(ctx context.Context, floatingIP *FloatingIP, opts FloatingIPChangeProtectionOpts) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_image_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_image_client_iface.go new file mode 100644 index 0000000000000..17fbcd929a014 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_image_client_iface.go @@ -0,0 +1,48 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IImageClient ... +type IImageClient interface { + // GetByID retrieves an image by its ID. If the image does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Image, *Response, error) + // GetByName retrieves an image by its name. If the image does not exist, nil is returned. + // + // Deprecated: Use [ImageClient.GetByNameAndArchitecture] instead. + GetByName(ctx context.Context, name string) (*Image, *Response, error) + // GetByNameAndArchitecture retrieves an image by its name and architecture. If the image does not exist, + // nil is returned. + // In contrast to [ImageClient.Get], this method also returns deprecated images. Depending on your needs you should + // check for this in your calling method. + GetByNameAndArchitecture(ctx context.Context, name string, architecture Architecture) (*Image, *Response, error) + // Get retrieves an image by its ID if the input can be parsed as an integer, otherwise it + // retrieves an image by its name. If the image does not exist, nil is returned. + // + // Deprecated: Use [ImageClient.GetForArchitecture] instead. + Get(ctx context.Context, idOrName string) (*Image, *Response, error) + // GetForArchitecture retrieves an image by its ID if the input can be parsed as an integer, otherwise it + // retrieves an image by its name and architecture. If the image does not exist, nil is returned. + // + // In contrast to [ImageClient.Get], this method also returns deprecated images. Depending on your needs you should + // check for this in your calling method. + GetForArchitecture(ctx context.Context, idOrName string, architecture Architecture) (*Image, *Response, error) + // List returns a list of images for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts ImageListOpts) ([]*Image, *Response, error) + // All returns all images. + All(ctx context.Context) ([]*Image, error) + // AllWithOpts returns all images for the given options. + AllWithOpts(ctx context.Context, opts ImageListOpts) ([]*Image, error) + // Delete deletes an image. + Delete(ctx context.Context, image *Image) (*Response, error) + // Update updates an image. + Update(ctx context.Context, image *Image, opts ImageUpdateOpts) (*Image, *Response, error) + // ChangeProtection changes the resource protection level of an image. + ChangeProtection(ctx context.Context, image *Image, opts ImageChangeProtectionOpts) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_iso_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_iso_client_iface.go new file mode 100644 index 0000000000000..aff450edffdbc --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_iso_client_iface.go @@ -0,0 +1,26 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IISOClient ... +type IISOClient interface { + // GetByID retrieves an ISO by its ID. + GetByID(ctx context.Context, id int64) (*ISO, *Response, error) + // GetByName retrieves an ISO by its name. + GetByName(ctx context.Context, name string) (*ISO, *Response, error) + // Get retrieves an ISO by its ID if the input can be parsed as an integer, otherwise it retrieves an ISO by its name. + Get(ctx context.Context, idOrName string) (*ISO, *Response, error) + // List returns a list of ISOs for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts ISOListOpts) ([]*ISO, *Response, error) + // All returns all ISOs. + All(ctx context.Context) ([]*ISO, error) + // AllWithOpts returns all ISOs for the given options. + AllWithOpts(ctx context.Context, opts ISOListOpts) ([]*ISO, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_load_balancer_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_load_balancer_client_iface.go new file mode 100644 index 0000000000000..16a635954a3cd --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_load_balancer_client_iface.go @@ -0,0 +1,71 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" + "net" +) + +// ILoadBalancerClient ... +type ILoadBalancerClient interface { + // GetByID retrieves a Load Balancer by its ID. If the Load Balancer does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*LoadBalancer, *Response, error) + // GetByName retrieves a Load Balancer by its name. If the Load Balancer does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*LoadBalancer, *Response, error) + // Get retrieves a Load Balancer by its ID if the input can be parsed as an integer, otherwise it + // retrieves a Load Balancer by its name. If the Load Balancer does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*LoadBalancer, *Response, error) + // List returns a list of Load Balancers for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts LoadBalancerListOpts) ([]*LoadBalancer, *Response, error) + // All returns all Load Balancers. + All(ctx context.Context) ([]*LoadBalancer, error) + // AllWithOpts returns all Load Balancers for the given options. + AllWithOpts(ctx context.Context, opts LoadBalancerListOpts) ([]*LoadBalancer, error) + // Update updates a Load Balancer. + Update(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerUpdateOpts) (*LoadBalancer, *Response, error) + // Create creates a new Load Balancer. + Create(ctx context.Context, opts LoadBalancerCreateOpts) (LoadBalancerCreateResult, *Response, error) + // Delete deletes a Load Balancer. + Delete(ctx context.Context, loadBalancer *LoadBalancer) (*Response, error) + // AddServerTarget adds a server target to a Load Balancer. + AddServerTarget(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddServerTargetOpts) (*Action, *Response, error) + // RemoveServerTarget removes a server target from a Load Balancer. + RemoveServerTarget(ctx context.Context, loadBalancer *LoadBalancer, server *Server) (*Action, *Response, error) + // AddLabelSelectorTarget adds a label selector target to a Load Balancer. + AddLabelSelectorTarget(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddLabelSelectorTargetOpts) (*Action, *Response, error) + // RemoveLabelSelectorTarget removes a label selector target from a Load Balancer. + RemoveLabelSelectorTarget(ctx context.Context, loadBalancer *LoadBalancer, labelSelector string) (*Action, *Response, error) + // AddIPTarget adds an IP target to a Load Balancer. + AddIPTarget(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddIPTargetOpts) (*Action, *Response, error) + // RemoveIPTarget removes an IP target from a Load Balancer. + RemoveIPTarget(ctx context.Context, loadBalancer *LoadBalancer, ip net.IP) (*Action, *Response, error) + // AddService adds a service to a Load Balancer. + AddService(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAddServiceOpts) (*Action, *Response, error) + // UpdateService updates a Load Balancer service. + UpdateService(ctx context.Context, loadBalancer *LoadBalancer, listenPort int, opts LoadBalancerUpdateServiceOpts) (*Action, *Response, error) + // DeleteService deletes a Load Balancer service. + DeleteService(ctx context.Context, loadBalancer *LoadBalancer, listenPort int) (*Action, *Response, error) + // ChangeProtection changes the resource protection level of a Load Balancer. + ChangeProtection(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeProtectionOpts) (*Action, *Response, error) + // ChangeAlgorithm changes the algorithm of a Load Balancer. + ChangeAlgorithm(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeAlgorithmOpts) (*Action, *Response, error) + // AttachToNetwork attaches a Load Balancer to a network. + AttachToNetwork(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerAttachToNetworkOpts) (*Action, *Response, error) + // DetachFromNetwork detaches a Load Balancer from a network. + DetachFromNetwork(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerDetachFromNetworkOpts) (*Action, *Response, error) + // EnablePublicInterface enables the Load Balancer's public network interface. + EnablePublicInterface(ctx context.Context, loadBalancer *LoadBalancer) (*Action, *Response, error) + // DisablePublicInterface disables the Load Balancer's public network interface. + DisablePublicInterface(ctx context.Context, loadBalancer *LoadBalancer) (*Action, *Response, error) + // ChangeType changes a Load Balancer's type. + ChangeType(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerChangeTypeOpts) (*Action, *Response, error) + // GetMetrics obtains metrics for a Load Balancer. + GetMetrics(ctx context.Context, loadBalancer *LoadBalancer, opts LoadBalancerGetMetricsOpts) (*LoadBalancerMetrics, *Response, error) + // ChangeDNSPtr changes or resets the reverse DNS pointer for a Load Balancer. + // Pass a nil ptr to reset the reverse DNS pointer to its default value. + ChangeDNSPtr(ctx context.Context, lb *LoadBalancer, ip string, ptr *string) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_load_balancer_type_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_load_balancer_type_client_iface.go new file mode 100644 index 0000000000000..fd3289d4df2ed --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_load_balancer_type_client_iface.go @@ -0,0 +1,27 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// ILoadBalancerTypeClient ... +type ILoadBalancerTypeClient interface { + // GetByID retrieves a Load Balancer type by its ID. If the Load Balancer type does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*LoadBalancerType, *Response, error) + // GetByName retrieves a Load Balancer type by its name. If the Load Balancer type does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*LoadBalancerType, *Response, error) + // Get retrieves a Load Balancer type by its ID if the input can be parsed as an integer, otherwise it + // retrieves a Load Balancer type by its name. If the Load Balancer type does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*LoadBalancerType, *Response, error) + // List returns a list of Load Balancer types for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts LoadBalancerTypeListOpts) ([]*LoadBalancerType, *Response, error) + // All returns all Load Balancer types. + All(ctx context.Context) ([]*LoadBalancerType, error) + // AllWithOpts returns all Load Balancer types for the given options. + AllWithOpts(ctx context.Context, opts LoadBalancerTypeListOpts) ([]*LoadBalancerType, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_location_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_location_client_iface.go new file mode 100644 index 0000000000000..9da4d5f6bd7c8 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_location_client_iface.go @@ -0,0 +1,27 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// ILocationClient ... +type ILocationClient interface { + // GetByID retrieves a location by its ID. If the location does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Location, *Response, error) + // GetByName retrieves an location by its name. If the location does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Location, *Response, error) + // Get retrieves a location by its ID if the input can be parsed as an integer, otherwise it + // retrieves a location by its name. If the location does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Location, *Response, error) + // List returns a list of locations for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts LocationListOpts) ([]*Location, *Response, error) + // All returns all locations. + All(ctx context.Context) ([]*Location, error) + // AllWithOpts returns all locations for the given options. + AllWithOpts(ctx context.Context, opts LocationListOpts) ([]*Location, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go new file mode 100644 index 0000000000000..f8b752e347861 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go @@ -0,0 +1,45 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// INetworkClient ... +type INetworkClient interface { + // GetByID retrieves a network by its ID. If the network does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Network, *Response, error) + // GetByName retrieves a network by its name. If the network does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Network, *Response, error) + // Get retrieves a network by its ID if the input can be parsed as an integer, otherwise it + // retrieves a network by its name. If the network does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Network, *Response, error) + // List returns a list of networks for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts NetworkListOpts) ([]*Network, *Response, error) + // All returns all networks. + All(ctx context.Context) ([]*Network, error) + // AllWithOpts returns all networks for the given options. + AllWithOpts(ctx context.Context, opts NetworkListOpts) ([]*Network, error) + // Delete deletes a network. + Delete(ctx context.Context, network *Network) (*Response, error) + // Update updates a network. + Update(ctx context.Context, network *Network, opts NetworkUpdateOpts) (*Network, *Response, error) + // Create creates a new network. + Create(ctx context.Context, opts NetworkCreateOpts) (*Network, *Response, error) + // ChangeIPRange changes the IP range of a network. + ChangeIPRange(ctx context.Context, network *Network, opts NetworkChangeIPRangeOpts) (*Action, *Response, error) + // AddSubnet adds a subnet to a network. + AddSubnet(ctx context.Context, network *Network, opts NetworkAddSubnetOpts) (*Action, *Response, error) + // DeleteSubnet deletes a subnet from a network. + DeleteSubnet(ctx context.Context, network *Network, opts NetworkDeleteSubnetOpts) (*Action, *Response, error) + // AddRoute adds a route to a network. + AddRoute(ctx context.Context, network *Network, opts NetworkAddRouteOpts) (*Action, *Response, error) + // DeleteRoute deletes a route from a network. + DeleteRoute(ctx context.Context, network *Network, opts NetworkDeleteRouteOpts) (*Action, *Response, error) + // ChangeProtection changes the resource protection level of a network. + ChangeProtection(ctx context.Context, network *Network, opts NetworkChangeProtectionOpts) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_placement_group_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_placement_group_client_iface.go new file mode 100644 index 0000000000000..9fadd4f2cba7c --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_placement_group_client_iface.go @@ -0,0 +1,33 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IPlacementGroupClient ... +type IPlacementGroupClient interface { + // GetByID retrieves a PlacementGroup by its ID. If the PlacementGroup does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*PlacementGroup, *Response, error) + // GetByName retrieves a PlacementGroup by its name. If the PlacementGroup does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*PlacementGroup, *Response, error) + // Get retrieves a PlacementGroup by its ID if the input can be parsed as an integer, otherwise it + // retrieves a PlacementGroup by its name. If the PlacementGroup does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*PlacementGroup, *Response, error) + // List returns a list of PlacementGroups for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts PlacementGroupListOpts) ([]*PlacementGroup, *Response, error) + // All returns all PlacementGroups. + All(ctx context.Context) ([]*PlacementGroup, error) + // AllWithOpts returns all PlacementGroups for the given options. + AllWithOpts(ctx context.Context, opts PlacementGroupListOpts) ([]*PlacementGroup, error) + // Create creates a new PlacementGroup. + Create(ctx context.Context, opts PlacementGroupCreateOpts) (PlacementGroupCreateResult, *Response, error) + // Update updates a PlacementGroup. + Update(ctx context.Context, placementGroup *PlacementGroup, opts PlacementGroupUpdateOpts) (*PlacementGroup, *Response, error) + // Delete deletes a PlacementGroup. + Delete(ctx context.Context, placementGroup *PlacementGroup) (*Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_pricing_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_pricing_client_iface.go new file mode 100644 index 0000000000000..cd4068c6228d4 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_pricing_client_iface.go @@ -0,0 +1,13 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IPricingClient ... +type IPricingClient interface { + // Get retrieves pricing information. + Get(ctx context.Context) (Pricing, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_primary_ip_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_primary_ip_client_iface.go new file mode 100644 index 0000000000000..94390d475a2be --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_primary_ip_client_iface.go @@ -0,0 +1,43 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IPrimaryIPClient ... +type IPrimaryIPClient interface { + // GetByID retrieves a Primary IP by its ID. If the Primary IP does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*PrimaryIP, *Response, error) + // GetByIP retrieves a Primary IP by its IP Address. If the Primary IP does not exist, nil is returned. + GetByIP(ctx context.Context, ip string) (*PrimaryIP, *Response, error) + // GetByName retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*PrimaryIP, *Response, error) + // Get retrieves a Primary IP by its ID if the input can be parsed as an integer, otherwise it + // retrieves a Primary IP by its name. If the Primary IP does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*PrimaryIP, *Response, error) + // List returns a list of Primary IPs for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, *Response, error) + // All returns all Primary IPs. + All(ctx context.Context) ([]*PrimaryIP, error) + // AllWithOpts returns all Primary IPs for the given options. + AllWithOpts(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, error) + // Create creates a Primary IP. + Create(ctx context.Context, opts PrimaryIPCreateOpts) (*PrimaryIPCreateResult, *Response, error) + // Delete deletes a Primary IP. + Delete(ctx context.Context, primaryIP *PrimaryIP) (*Response, error) + // Update updates a Primary IP. + Update(ctx context.Context, primaryIP *PrimaryIP, opts PrimaryIPUpdateOpts) (*PrimaryIP, *Response, error) + // Assign a Primary IP to a resource. + Assign(ctx context.Context, opts PrimaryIPAssignOpts) (*Action, *Response, error) + // Unassign a Primary IP from a resource. + Unassign(ctx context.Context, id int64) (*Action, *Response, error) + // ChangeDNSPtr Change the reverse DNS from a Primary IP. + ChangeDNSPtr(ctx context.Context, opts PrimaryIPChangeDNSPtrOpts) (*Action, *Response, error) + // ChangeProtection Changes the protection configuration of a Primary IP. + ChangeProtection(ctx context.Context, opts PrimaryIPChangeProtectionOpts) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_rdns_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_rdns_client_iface.go new file mode 100644 index 0000000000000..f92f186779f49 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_rdns_client_iface.go @@ -0,0 +1,15 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" + "net" +) + +// IRDNSClient ... +type IRDNSClient interface { + // ChangeDNSPtr changes or resets the reverse DNS pointer for a IP address. + // Pass a nil ptr to reset the reverse DNS pointer to its default value. + ChangeDNSPtr(ctx context.Context, rdns RDNSSupporter, ip net.IP, ptr *string) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_resource_action_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_resource_action_client_iface.go new file mode 100644 index 0000000000000..67910ab223a87 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_resource_action_client_iface.go @@ -0,0 +1,20 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IResourceActionClient ... +type IResourceActionClient interface { + // GetByID retrieves an action by its ID. If the action does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Action, *Response, error) + // List returns a list of actions for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts ActionListOpts) ([]*Action, *Response, error) + // All returns all actions for the given options. + All(ctx context.Context, opts ActionListOpts) ([]*Action, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go new file mode 100644 index 0000000000000..25c5893b4bee7 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go @@ -0,0 +1,2350 @@ +// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. +//go:build !goverter + +package hcloud + +import ( + schema "github.com/hetznercloud/hcloud-go/v2/hcloud/schema" + "net" + "time" +) + +type converterImpl struct{} + +func (c *converterImpl) ActionFromSchema(source schema.Action) *Action { + var hcloudAction Action + hcloudAction.ID = source.ID + hcloudAction.Status = ActionStatus(source.Status) + hcloudAction.Command = source.Command + hcloudAction.Progress = source.Progress + hcloudAction.Started = source.Started + hcloudAction.Finished = c.pTimeTimeToTimeTime(source.Finished) + var pString *string + if source.Error != nil { + pString = &source.Error.Code + } + if pString != nil { + hcloudAction.ErrorCode = *pString + } + var pString2 *string + if source.Error != nil { + pString2 = &source.Error.Message + } + if pString2 != nil { + hcloudAction.ErrorMessage = *pString2 + } + if source.Resources != nil { + hcloudAction.Resources = make([]*ActionResource, len(source.Resources)) + for i := 0; i < len(source.Resources); i++ { + hcloudAction.Resources[i] = c.schemaActionResourceReferenceToPHcloudActionResource(source.Resources[i]) + } + } + return &hcloudAction +} +func (c *converterImpl) ActionsFromSchema(source []schema.Action) []*Action { + var pHcloudActionList []*Action + if source != nil { + pHcloudActionList = make([]*Action, len(source)) + for i := 0; i < len(source); i++ { + pHcloudActionList[i] = c.ActionFromSchema(source[i]) + } + } + return pHcloudActionList +} +func (c *converterImpl) CertificateFromSchema(source schema.Certificate) *Certificate { + var hcloudCertificate Certificate + hcloudCertificate.ID = source.ID + hcloudCertificate.Name = source.Name + hcloudCertificate.Labels = source.Labels + hcloudCertificate.Type = CertificateType(source.Type) + hcloudCertificate.Certificate = source.Certificate + hcloudCertificate.Created = c.timeTimeToTimeTime(source.Created) + hcloudCertificate.NotValidBefore = c.timeTimeToTimeTime(source.NotValidBefore) + hcloudCertificate.NotValidAfter = c.timeTimeToTimeTime(source.NotValidAfter) + hcloudCertificate.DomainNames = source.DomainNames + hcloudCertificate.Fingerprint = source.Fingerprint + hcloudCertificate.Status = c.pSchemaCertificateStatusRefToPHcloudCertificateStatus(source.Status) + if source.UsedBy != nil { + hcloudCertificate.UsedBy = make([]CertificateUsedByRef, len(source.UsedBy)) + for i := 0; i < len(source.UsedBy); i++ { + hcloudCertificate.UsedBy[i] = c.schemaCertificateUsedByRefToHcloudCertificateUsedByRef(source.UsedBy[i]) + } + } + return &hcloudCertificate +} +func (c *converterImpl) DatacenterFromSchema(source schema.Datacenter) *Datacenter { + var hcloudDatacenter Datacenter + hcloudDatacenter.ID = source.ID + hcloudDatacenter.Name = source.Name + hcloudDatacenter.Description = source.Description + hcloudDatacenter.Location = c.LocationFromSchema(source.Location) + hcloudDatacenter.ServerTypes = c.schemaDatacenterServerTypesToHcloudDatacenterServerTypes(source.ServerTypes) + return &hcloudDatacenter +} +func (c *converterImpl) DeprecationFromSchema(source *schema.DeprecationInfo) *DeprecationInfo { + var pHcloudDeprecationInfo *DeprecationInfo + if source != nil { + var hcloudDeprecationInfo DeprecationInfo + hcloudDeprecationInfo.Announced = c.timeTimeToTimeTime((*source).Announced) + hcloudDeprecationInfo.UnavailableAfter = c.timeTimeToTimeTime((*source).UnavailableAfter) + pHcloudDeprecationInfo = &hcloudDeprecationInfo + } + return pHcloudDeprecationInfo +} +func (c *converterImpl) ErrorFromSchema(source schema.Error) Error { + var hcloudError Error + hcloudError.Code = ErrorCode(source.Code) + hcloudError.Message = source.Message + hcloudError.Details = errorDetailsFromSchema(source.Details) + return hcloudError +} +func (c *converterImpl) FirewallFromSchema(source schema.Firewall) *Firewall { + var hcloudFirewall Firewall + hcloudFirewall.ID = source.ID + hcloudFirewall.Name = source.Name + hcloudFirewall.Labels = source.Labels + hcloudFirewall.Created = c.timeTimeToTimeTime(source.Created) + if source.Rules != nil { + hcloudFirewall.Rules = make([]FirewallRule, len(source.Rules)) + for i := 0; i < len(source.Rules); i++ { + hcloudFirewall.Rules[i] = c.schemaFirewallRuleToHcloudFirewallRule(source.Rules[i]) + } + } + if source.AppliedTo != nil { + hcloudFirewall.AppliedTo = make([]FirewallResource, len(source.AppliedTo)) + for j := 0; j < len(source.AppliedTo); j++ { + hcloudFirewall.AppliedTo[j] = c.schemaFirewallResourceToHcloudFirewallResource(source.AppliedTo[j]) + } + } + return &hcloudFirewall +} +func (c *converterImpl) FloatingIPFromSchema(source schema.FloatingIP) *FloatingIP { + var hcloudFloatingIP FloatingIP + hcloudFloatingIP.ID = source.ID + if source.Description != nil { + hcloudFloatingIP.Description = *source.Description + } + hcloudFloatingIP.Created = c.timeTimeToTimeTime(source.Created) + hcloudFloatingIP.IP = ipFromFloatingIPSchema(source) + hcloudFloatingIP.Network = networkFromFloatingIPSchema(source) + hcloudFloatingIP.Type = FloatingIPType(source.Type) + if source.Server != nil { + hcloudServer := serverFromInt64(*source.Server) + hcloudFloatingIP.Server = &hcloudServer + } + hcloudFloatingIP.DNSPtr = mapFromFloatingIPDNSPtrSchema(source.DNSPtr) + hcloudFloatingIP.HomeLocation = c.LocationFromSchema(source.HomeLocation) + hcloudFloatingIP.Blocked = source.Blocked + hcloudFloatingIP.Protection = c.schemaFloatingIPProtectionToHcloudFloatingIPProtection(source.Protection) + hcloudFloatingIP.Labels = source.Labels + hcloudFloatingIP.Name = source.Name + return &hcloudFloatingIP +} +func (c *converterImpl) ISOFromSchema(source schema.ISO) *ISO { + hcloudISO := c.intISOFromSchema(source) + return &hcloudISO +} +func (c *converterImpl) ImageFromSchema(source schema.Image) *Image { + var hcloudImage Image + hcloudImage.ID = source.ID + if source.Name != nil { + hcloudImage.Name = *source.Name + } + hcloudImage.Type = ImageType(source.Type) + hcloudImage.Status = ImageStatus(source.Status) + hcloudImage.Description = source.Description + if source.ImageSize != nil { + hcloudImage.ImageSize = *source.ImageSize + } + hcloudImage.DiskSize = source.DiskSize + hcloudImage.Created = c.pTimeTimeToTimeTime(source.Created) + hcloudImage.CreatedFrom = c.pSchemaImageCreatedFromToPHcloudServer(source.CreatedFrom) + if source.BoundTo != nil { + hcloudServer := serverFromInt64(*source.BoundTo) + hcloudImage.BoundTo = &hcloudServer + } + hcloudImage.RapidDeploy = source.RapidDeploy + hcloudImage.OSFlavor = source.OSFlavor + if source.OSVersion != nil { + hcloudImage.OSVersion = *source.OSVersion + } + hcloudImage.Architecture = Architecture(source.Architecture) + hcloudImage.Protection = c.schemaImageProtectionToHcloudImageProtection(source.Protection) + hcloudImage.Deprecated = c.pTimeTimeToTimeTime(source.Deprecated) + hcloudImage.Labels = source.Labels + hcloudImage.Deleted = c.pTimeTimeToTimeTime(source.Deleted) + return &hcloudImage +} +func (c *converterImpl) LoadBalancerFromSchema(source schema.LoadBalancer) *LoadBalancer { + var hcloudLoadBalancer LoadBalancer + hcloudLoadBalancer.ID = source.ID + hcloudLoadBalancer.Name = source.Name + hcloudLoadBalancer.PublicNet = c.schemaLoadBalancerPublicNetToHcloudLoadBalancerPublicNet(source.PublicNet) + if source.PrivateNet != nil { + hcloudLoadBalancer.PrivateNet = make([]LoadBalancerPrivateNet, len(source.PrivateNet)) + for i := 0; i < len(source.PrivateNet); i++ { + hcloudLoadBalancer.PrivateNet[i] = c.schemaLoadBalancerPrivateNetToHcloudLoadBalancerPrivateNet(source.PrivateNet[i]) + } + } + hcloudLoadBalancer.Location = c.LocationFromSchema(source.Location) + hcloudLoadBalancer.LoadBalancerType = c.LoadBalancerTypeFromSchema(source.LoadBalancerType) + hcloudLoadBalancer.Algorithm = c.schemaLoadBalancerAlgorithmToHcloudLoadBalancerAlgorithm(source.Algorithm) + if source.Services != nil { + hcloudLoadBalancer.Services = make([]LoadBalancerService, len(source.Services)) + for j := 0; j < len(source.Services); j++ { + hcloudLoadBalancer.Services[j] = c.LoadBalancerServiceFromSchema(source.Services[j]) + } + } + if source.Targets != nil { + hcloudLoadBalancer.Targets = make([]LoadBalancerTarget, len(source.Targets)) + for k := 0; k < len(source.Targets); k++ { + hcloudLoadBalancer.Targets[k] = c.LoadBalancerTargetFromSchema(source.Targets[k]) + } + } + hcloudLoadBalancer.Protection = c.schemaLoadBalancerProtectionToHcloudLoadBalancerProtection(source.Protection) + hcloudLoadBalancer.Labels = source.Labels + hcloudLoadBalancer.Created = c.timeTimeToTimeTime(source.Created) + hcloudLoadBalancer.IncludedTraffic = source.IncludedTraffic + if source.OutgoingTraffic != nil { + hcloudLoadBalancer.OutgoingTraffic = *source.OutgoingTraffic + } + if source.IngoingTraffic != nil { + hcloudLoadBalancer.IngoingTraffic = *source.IngoingTraffic + } + return &hcloudLoadBalancer +} +func (c *converterImpl) LoadBalancerMetricsFromSchema(source *schema.LoadBalancerGetMetricsResponse) (*LoadBalancerMetrics, error) { + var pHcloudLoadBalancerMetrics *LoadBalancerMetrics + if source != nil { + var hcloudLoadBalancerMetrics LoadBalancerMetrics + hcloudLoadBalancerMetrics.Start = c.timeTimeToTimeTime((*source).Metrics.Start) + hcloudLoadBalancerMetrics.End = c.timeTimeToTimeTime((*source).Metrics.End) + hcloudLoadBalancerMetrics.Step = (*source).Metrics.Step + if (*source).Metrics.TimeSeries != nil { + hcloudLoadBalancerMetrics.TimeSeries = make(map[string][]LoadBalancerMetricsValue, len((*source).Metrics.TimeSeries)) + for key, value := range (*source).Metrics.TimeSeries { + hcloudLoadBalancerMetricsValueList, err := loadBalancerMetricsTimeSeriesFromSchema(value) + if err != nil { + return nil, err + } + hcloudLoadBalancerMetrics.TimeSeries[key] = hcloudLoadBalancerMetricsValueList + } + } + pHcloudLoadBalancerMetrics = &hcloudLoadBalancerMetrics + } + return pHcloudLoadBalancerMetrics, nil +} +func (c *converterImpl) LoadBalancerServiceFromSchema(source schema.LoadBalancerService) LoadBalancerService { + var hcloudLoadBalancerService LoadBalancerService + hcloudLoadBalancerService.Protocol = LoadBalancerServiceProtocol(source.Protocol) + hcloudLoadBalancerService.ListenPort = source.ListenPort + hcloudLoadBalancerService.DestinationPort = source.DestinationPort + hcloudLoadBalancerService.Proxyprotocol = source.Proxyprotocol + hcloudLoadBalancerService.HTTP = c.pSchemaLoadBalancerServiceHTTPToHcloudLoadBalancerServiceHTTP(source.HTTP) + hcloudLoadBalancerService.HealthCheck = c.LoadBalancerServiceHealthCheckFromSchema(source.HealthCheck) + return hcloudLoadBalancerService +} +func (c *converterImpl) LoadBalancerServiceHealthCheckFromSchema(source *schema.LoadBalancerServiceHealthCheck) LoadBalancerServiceHealthCheck { + var hcloudLoadBalancerServiceHealthCheck LoadBalancerServiceHealthCheck + if source != nil { + var hcloudLoadBalancerServiceHealthCheck2 LoadBalancerServiceHealthCheck + hcloudLoadBalancerServiceHealthCheck2.Protocol = LoadBalancerServiceProtocol((*source).Protocol) + hcloudLoadBalancerServiceHealthCheck2.Port = (*source).Port + hcloudLoadBalancerServiceHealthCheck2.Interval = durationFromIntSeconds((*source).Interval) + hcloudLoadBalancerServiceHealthCheck2.Timeout = durationFromIntSeconds((*source).Timeout) + hcloudLoadBalancerServiceHealthCheck2.Retries = (*source).Retries + hcloudLoadBalancerServiceHealthCheck2.HTTP = c.pSchemaLoadBalancerServiceHealthCheckHTTPToPHcloudLoadBalancerServiceHealthCheckHTTP((*source).HTTP) + hcloudLoadBalancerServiceHealthCheck = hcloudLoadBalancerServiceHealthCheck2 + } + return hcloudLoadBalancerServiceHealthCheck +} +func (c *converterImpl) LoadBalancerTargetFromSchema(source schema.LoadBalancerTarget) LoadBalancerTarget { + var hcloudLoadBalancerTarget LoadBalancerTarget + hcloudLoadBalancerTarget.Type = LoadBalancerTargetType(source.Type) + hcloudLoadBalancerTarget.Server = c.pSchemaLoadBalancerTargetServerToPHcloudLoadBalancerTargetServer(source.Server) + hcloudLoadBalancerTarget.LabelSelector = c.pSchemaLoadBalancerTargetLabelSelectorToPHcloudLoadBalancerTargetLabelSelector(source.LabelSelector) + hcloudLoadBalancerTarget.IP = c.pSchemaLoadBalancerTargetIPToPHcloudLoadBalancerTargetIP(source.IP) + if source.HealthStatus != nil { + hcloudLoadBalancerTarget.HealthStatus = make([]LoadBalancerTargetHealthStatus, len(source.HealthStatus)) + for i := 0; i < len(source.HealthStatus); i++ { + hcloudLoadBalancerTarget.HealthStatus[i] = c.LoadBalancerTargetHealthStatusFromSchema(source.HealthStatus[i]) + } + } + if source.Targets != nil { + hcloudLoadBalancerTarget.Targets = make([]LoadBalancerTarget, len(source.Targets)) + for j := 0; j < len(source.Targets); j++ { + hcloudLoadBalancerTarget.Targets[j] = c.LoadBalancerTargetFromSchema(source.Targets[j]) + } + } + hcloudLoadBalancerTarget.UsePrivateIP = source.UsePrivateIP + return hcloudLoadBalancerTarget +} +func (c *converterImpl) LoadBalancerTargetHealthStatusFromSchema(source schema.LoadBalancerTargetHealthStatus) LoadBalancerTargetHealthStatus { + var hcloudLoadBalancerTargetHealthStatus LoadBalancerTargetHealthStatus + hcloudLoadBalancerTargetHealthStatus.ListenPort = source.ListenPort + hcloudLoadBalancerTargetHealthStatus.Status = LoadBalancerTargetHealthStatusStatus(source.Status) + return hcloudLoadBalancerTargetHealthStatus +} +func (c *converterImpl) LoadBalancerTargetServerFromSchema(source schema.LoadBalancerTargetServer) LoadBalancerTargetServer { + var hcloudLoadBalancerTargetServer LoadBalancerTargetServer + hcloudServer := serverFromInt64(source.ID) + hcloudLoadBalancerTargetServer.Server = &hcloudServer + return hcloudLoadBalancerTargetServer +} +func (c *converterImpl) LoadBalancerTypeFromSchema(source schema.LoadBalancerType) *LoadBalancerType { + var hcloudLoadBalancerType LoadBalancerType + hcloudLoadBalancerType.ID = source.ID + hcloudLoadBalancerType.Name = source.Name + hcloudLoadBalancerType.Description = source.Description + hcloudLoadBalancerType.MaxConnections = source.MaxConnections + hcloudLoadBalancerType.MaxServices = source.MaxServices + hcloudLoadBalancerType.MaxTargets = source.MaxTargets + hcloudLoadBalancerType.MaxAssignedCertificates = source.MaxAssignedCertificates + if source.Prices != nil { + hcloudLoadBalancerType.Pricings = make([]LoadBalancerTypeLocationPricing, len(source.Prices)) + for i := 0; i < len(source.Prices); i++ { + hcloudLoadBalancerType.Pricings[i] = c.LoadBalancerTypeLocationPricingFromSchema(source.Prices[i]) + } + } + hcloudLoadBalancerType.Deprecated = source.Deprecated + return &hcloudLoadBalancerType +} +func (c *converterImpl) LoadBalancerTypeLocationPricingFromSchema(source schema.PricingLoadBalancerTypePrice) LoadBalancerTypeLocationPricing { + var hcloudLoadBalancerTypeLocationPricing LoadBalancerTypeLocationPricing + hcloudLocation := locationFromString(source.Location) + hcloudLoadBalancerTypeLocationPricing.Location = &hcloudLocation + hcloudLoadBalancerTypeLocationPricing.Hourly = c.PriceFromSchema(source.PriceHourly) + hcloudLoadBalancerTypeLocationPricing.Monthly = c.PriceFromSchema(source.PriceMonthly) + hcloudLoadBalancerTypeLocationPricing.IncludedTraffic = source.IncludedTraffic + hcloudLoadBalancerTypeLocationPricing.PerTBTraffic = c.PriceFromSchema(source.PricePerTBTraffic) + return hcloudLoadBalancerTypeLocationPricing +} +func (c *converterImpl) LocationFromSchema(source schema.Location) *Location { + var hcloudLocation Location + hcloudLocation.ID = source.ID + hcloudLocation.Name = source.Name + hcloudLocation.Description = source.Description + hcloudLocation.Country = source.Country + hcloudLocation.City = source.City + hcloudLocation.Latitude = source.Latitude + hcloudLocation.Longitude = source.Longitude + hcloudLocation.NetworkZone = NetworkZone(source.NetworkZone) + return &hcloudLocation +} +func (c *converterImpl) NetworkFromSchema(source schema.Network) *Network { + var hcloudNetwork Network + hcloudNetwork.ID = source.ID + hcloudNetwork.Name = source.Name + hcloudNetwork.Created = c.timeTimeToTimeTime(source.Created) + netIPNet := ipNetFromString(source.IPRange) + hcloudNetwork.IPRange = &netIPNet + if source.Subnets != nil { + hcloudNetwork.Subnets = make([]NetworkSubnet, len(source.Subnets)) + for i := 0; i < len(source.Subnets); i++ { + hcloudNetwork.Subnets[i] = c.NetworkSubnetFromSchema(source.Subnets[i]) + } + } + if source.Routes != nil { + hcloudNetwork.Routes = make([]NetworkRoute, len(source.Routes)) + for j := 0; j < len(source.Routes); j++ { + hcloudNetwork.Routes[j] = c.NetworkRouteFromSchema(source.Routes[j]) + } + } + if source.Servers != nil { + hcloudNetwork.Servers = make([]*Server, len(source.Servers)) + for k := 0; k < len(source.Servers); k++ { + hcloudServer := serverFromInt64(source.Servers[k]) + hcloudNetwork.Servers[k] = &hcloudServer + } + } + if source.LoadBalancers != nil { + hcloudNetwork.LoadBalancers = make([]*LoadBalancer, len(source.LoadBalancers)) + for l := 0; l < len(source.LoadBalancers); l++ { + hcloudLoadBalancer := loadBalancerFromInt64(source.LoadBalancers[l]) + hcloudNetwork.LoadBalancers[l] = &hcloudLoadBalancer + } + } + hcloudNetwork.Protection = c.schemaNetworkProtectionToHcloudNetworkProtection(source.Protection) + hcloudNetwork.Labels = source.Labels + hcloudNetwork.ExposeRoutesToVSwitch = source.ExposeRoutesToVSwitch + return &hcloudNetwork +} +func (c *converterImpl) NetworkRouteFromSchema(source schema.NetworkRoute) NetworkRoute { + var hcloudNetworkRoute NetworkRoute + netIPNet := ipNetFromString(source.Destination) + hcloudNetworkRoute.Destination = &netIPNet + hcloudNetworkRoute.Gateway = ipFromString(source.Gateway) + return hcloudNetworkRoute +} +func (c *converterImpl) NetworkSubnetFromSchema(source schema.NetworkSubnet) NetworkSubnet { + var hcloudNetworkSubnet NetworkSubnet + hcloudNetworkSubnet.Type = NetworkSubnetType(source.Type) + netIPNet := ipNetFromString(source.IPRange) + hcloudNetworkSubnet.IPRange = &netIPNet + hcloudNetworkSubnet.NetworkZone = NetworkZone(source.NetworkZone) + hcloudNetworkSubnet.Gateway = ipFromString(source.Gateway) + hcloudNetworkSubnet.VSwitchID = source.VSwitchID + return hcloudNetworkSubnet +} +func (c *converterImpl) PaginationFromSchema(source schema.MetaPagination) Pagination { + var hcloudPagination Pagination + hcloudPagination.Page = source.Page + hcloudPagination.PerPage = source.PerPage + hcloudPagination.PreviousPage = source.PreviousPage + hcloudPagination.NextPage = source.NextPage + hcloudPagination.LastPage = source.LastPage + hcloudPagination.TotalEntries = source.TotalEntries + return hcloudPagination +} +func (c *converterImpl) PlacementGroupFromSchema(source schema.PlacementGroup) *PlacementGroup { + var hcloudPlacementGroup PlacementGroup + hcloudPlacementGroup.ID = source.ID + hcloudPlacementGroup.Name = source.Name + hcloudPlacementGroup.Labels = source.Labels + hcloudPlacementGroup.Created = c.timeTimeToTimeTime(source.Created) + hcloudPlacementGroup.Servers = source.Servers + hcloudPlacementGroup.Type = PlacementGroupType(source.Type) + return &hcloudPlacementGroup +} +func (c *converterImpl) PriceFromSchema(source schema.Price) Price { + var hcloudPrice Price + hcloudPrice.Net = source.Net + hcloudPrice.Gross = source.Gross + return hcloudPrice +} +func (c *converterImpl) PricingFromSchema(source schema.Pricing) Pricing { + var hcloudPricing Pricing + hcloudPricing.Image = imagePricingFromSchema(source) + hcloudPricing.FloatingIP = floatingIPPricingFromSchema(source) + hcloudPricing.FloatingIPs = floatingIPTypePricingFromSchema(source) + hcloudPricing.PrimaryIPs = primaryIPPricingFromSchema(source) + hcloudPricing.Traffic = trafficPricingFromSchema(source) + hcloudPricing.ServerBackup = c.schemaPricingServerBackupToHcloudServerBackupPricing(source.ServerBackup) + hcloudPricing.ServerTypes = serverTypePricingFromSchema(source) + hcloudPricing.LoadBalancerTypes = loadBalancerTypePricingFromSchema(source) + hcloudPricing.Volume = volumePricingFromSchema(source) + return hcloudPricing +} +func (c *converterImpl) PrimaryIPFromSchema(source schema.PrimaryIP) *PrimaryIP { + var hcloudPrimaryIP PrimaryIP + hcloudPrimaryIP.ID = source.ID + hcloudPrimaryIP.IP = ipFromPrimaryIPSchema(source) + hcloudPrimaryIP.Network = networkFromPrimaryIPSchema(source) + hcloudPrimaryIP.Labels = source.Labels + hcloudPrimaryIP.Name = source.Name + hcloudPrimaryIP.Type = PrimaryIPType(source.Type) + hcloudPrimaryIP.Protection = c.schemaPrimaryIPProtectionToHcloudPrimaryIPProtection(source.Protection) + hcloudPrimaryIP.DNSPtr = mapFromPrimaryIPDNSPtrSchema(source.DNSPtr) + if source.AssigneeID != nil { + hcloudPrimaryIP.AssigneeID = *source.AssigneeID + } + hcloudPrimaryIP.AssigneeType = source.AssigneeType + hcloudPrimaryIP.AutoDelete = source.AutoDelete + hcloudPrimaryIP.Blocked = source.Blocked + hcloudPrimaryIP.Created = c.timeTimeToTimeTime(source.Created) + hcloudPrimaryIP.Datacenter = c.DatacenterFromSchema(source.Datacenter) + return &hcloudPrimaryIP +} +func (c *converterImpl) SSHKeyFromSchema(source schema.SSHKey) *SSHKey { + var hcloudSSHKey SSHKey + hcloudSSHKey.ID = source.ID + hcloudSSHKey.Name = source.Name + hcloudSSHKey.Fingerprint = source.Fingerprint + hcloudSSHKey.PublicKey = source.PublicKey + hcloudSSHKey.Labels = source.Labels + hcloudSSHKey.Created = c.timeTimeToTimeTime(source.Created) + return &hcloudSSHKey +} +func (c *converterImpl) SchemaFromAction(source *Action) schema.Action { + var schemaAction schema.Action + if source != nil { + var schemaAction2 schema.Action + schemaAction2.ID = (*source).ID + schemaAction2.Status = string((*source).Status) + schemaAction2.Command = (*source).Command + schemaAction2.Progress = (*source).Progress + schemaAction2.Started = c.timeTimeToTimeTime((*source).Started) + schemaAction2.Finished = timeToTimePtr((*source).Finished) + schemaAction2.Error = schemaActionErrorFromAction((*source)) + if (*source).Resources != nil { + schemaAction2.Resources = make([]schema.ActionResourceReference, len((*source).Resources)) + for i := 0; i < len((*source).Resources); i++ { + schemaAction2.Resources[i] = c.pHcloudActionResourceToSchemaActionResourceReference((*source).Resources[i]) + } + } + schemaAction = schemaAction2 + } + return schemaAction +} +func (c *converterImpl) SchemaFromActions(source []*Action) []schema.Action { + var schemaActionList []schema.Action + if source != nil { + schemaActionList = make([]schema.Action, len(source)) + for i := 0; i < len(source); i++ { + schemaActionList[i] = c.SchemaFromAction(source[i]) + } + } + return schemaActionList +} +func (c *converterImpl) SchemaFromCertificate(source *Certificate) schema.Certificate { + var schemaCertificate schema.Certificate + if source != nil { + var schemaCertificate2 schema.Certificate + schemaCertificate2.ID = (*source).ID + schemaCertificate2.Name = (*source).Name + schemaCertificate2.Labels = (*source).Labels + schemaCertificate2.Type = string((*source).Type) + schemaCertificate2.Certificate = (*source).Certificate + schemaCertificate2.Created = c.timeTimeToTimeTime((*source).Created) + schemaCertificate2.NotValidBefore = c.timeTimeToTimeTime((*source).NotValidBefore) + schemaCertificate2.NotValidAfter = c.timeTimeToTimeTime((*source).NotValidAfter) + schemaCertificate2.DomainNames = (*source).DomainNames + schemaCertificate2.Fingerprint = (*source).Fingerprint + schemaCertificate2.Status = c.pHcloudCertificateStatusToPSchemaCertificateStatusRef((*source).Status) + if (*source).UsedBy != nil { + schemaCertificate2.UsedBy = make([]schema.CertificateUsedByRef, len((*source).UsedBy)) + for i := 0; i < len((*source).UsedBy); i++ { + schemaCertificate2.UsedBy[i] = c.hcloudCertificateUsedByRefToSchemaCertificateUsedByRef((*source).UsedBy[i]) + } + } + schemaCertificate = schemaCertificate2 + } + return schemaCertificate +} +func (c *converterImpl) SchemaFromDatacenter(source *Datacenter) schema.Datacenter { + var schemaDatacenter schema.Datacenter + if source != nil { + var schemaDatacenter2 schema.Datacenter + schemaDatacenter2.ID = (*source).ID + schemaDatacenter2.Name = (*source).Name + schemaDatacenter2.Description = (*source).Description + schemaDatacenter2.Location = c.SchemaFromLocation((*source).Location) + schemaDatacenter2.ServerTypes = c.hcloudDatacenterServerTypesToSchemaDatacenterServerTypes((*source).ServerTypes) + schemaDatacenter = schemaDatacenter2 + } + return schemaDatacenter +} +func (c *converterImpl) SchemaFromDeprecation(source *DeprecationInfo) *schema.DeprecationInfo { + var pSchemaDeprecationInfo *schema.DeprecationInfo + if source != nil { + var schemaDeprecationInfo schema.DeprecationInfo + schemaDeprecationInfo.Announced = c.timeTimeToTimeTime((*source).Announced) + schemaDeprecationInfo.UnavailableAfter = c.timeTimeToTimeTime((*source).UnavailableAfter) + pSchemaDeprecationInfo = &schemaDeprecationInfo + } + return pSchemaDeprecationInfo +} +func (c *converterImpl) SchemaFromError(source Error) schema.Error { + var schemaError schema.Error + schemaError.Code = string(source.Code) + schemaError.Message = source.Message + schemaError.DetailsRaw = rawSchemaFromErrorDetails(source.Details) + schemaError.Details = schemaFromErrorDetails(source.Details) + return schemaError +} +func (c *converterImpl) SchemaFromFirewall(source *Firewall) schema.Firewall { + var schemaFirewall schema.Firewall + if source != nil { + var schemaFirewall2 schema.Firewall + schemaFirewall2.ID = (*source).ID + schemaFirewall2.Name = (*source).Name + schemaFirewall2.Labels = (*source).Labels + schemaFirewall2.Created = c.timeTimeToTimeTime((*source).Created) + if (*source).Rules != nil { + schemaFirewall2.Rules = make([]schema.FirewallRule, len((*source).Rules)) + for i := 0; i < len((*source).Rules); i++ { + schemaFirewall2.Rules[i] = c.hcloudFirewallRuleToSchemaFirewallRule((*source).Rules[i]) + } + } + if (*source).AppliedTo != nil { + schemaFirewall2.AppliedTo = make([]schema.FirewallResource, len((*source).AppliedTo)) + for j := 0; j < len((*source).AppliedTo); j++ { + schemaFirewall2.AppliedTo[j] = c.SchemaFromFirewallResource((*source).AppliedTo[j]) + } + } + schemaFirewall = schemaFirewall2 + } + return schemaFirewall +} +func (c *converterImpl) SchemaFromFirewallCreateOpts(source FirewallCreateOpts) schema.FirewallCreateRequest { + var schemaFirewallCreateRequest schema.FirewallCreateRequest + schemaFirewallCreateRequest.Name = source.Name + schemaFirewallCreateRequest.Labels = stringMapToStringMapPtr(source.Labels) + if source.Rules != nil { + schemaFirewallCreateRequest.Rules = make([]schema.FirewallRuleRequest, len(source.Rules)) + for i := 0; i < len(source.Rules); i++ { + schemaFirewallCreateRequest.Rules[i] = c.hcloudFirewallRuleToSchemaFirewallRuleRequest(source.Rules[i]) + } + } + if source.ApplyTo != nil { + schemaFirewallCreateRequest.ApplyTo = make([]schema.FirewallResource, len(source.ApplyTo)) + for j := 0; j < len(source.ApplyTo); j++ { + schemaFirewallCreateRequest.ApplyTo[j] = c.SchemaFromFirewallResource(source.ApplyTo[j]) + } + } + return schemaFirewallCreateRequest +} +func (c *converterImpl) SchemaFromFirewallResource(source FirewallResource) schema.FirewallResource { + var schemaFirewallResource schema.FirewallResource + schemaFirewallResource.Type = string(source.Type) + schemaFirewallResource.Server = c.pHcloudFirewallResourceServerToPSchemaFirewallResourceServer(source.Server) + schemaFirewallResource.LabelSelector = c.pHcloudFirewallResourceLabelSelectorToPSchemaFirewallResourceLabelSelector(source.LabelSelector) + return schemaFirewallResource +} +func (c *converterImpl) SchemaFromFirewallSetRulesOpts(source FirewallSetRulesOpts) schema.FirewallActionSetRulesRequest { + var schemaFirewallActionSetRulesRequest schema.FirewallActionSetRulesRequest + if source.Rules != nil { + schemaFirewallActionSetRulesRequest.Rules = make([]schema.FirewallRuleRequest, len(source.Rules)) + for i := 0; i < len(source.Rules); i++ { + schemaFirewallActionSetRulesRequest.Rules[i] = c.hcloudFirewallRuleToSchemaFirewallRuleRequest(source.Rules[i]) + } + } + return schemaFirewallActionSetRulesRequest +} +func (c *converterImpl) SchemaFromFloatingIP(source *FloatingIP) schema.FloatingIP { + var schemaFloatingIP schema.FloatingIP + if source != nil { + var schemaFloatingIP2 schema.FloatingIP + schemaFloatingIP2.ID = (*source).ID + pString := (*source).Description + schemaFloatingIP2.Description = &pString + schemaFloatingIP2.Created = c.timeTimeToTimeTime((*source).Created) + schemaFloatingIP2.IP = floatingIPToIPString((*source)) + schemaFloatingIP2.Type = string((*source).Type) + schemaFloatingIP2.Server = c.pHcloudServerToPInt64((*source).Server) + schemaFloatingIP2.DNSPtr = floatingIPDNSPtrSchemaFromMap((*source).DNSPtr) + schemaFloatingIP2.HomeLocation = c.SchemaFromLocation((*source).HomeLocation) + schemaFloatingIP2.Blocked = (*source).Blocked + schemaFloatingIP2.Protection = c.hcloudFloatingIPProtectionToSchemaFloatingIPProtection((*source).Protection) + schemaFloatingIP2.Labels = (*source).Labels + schemaFloatingIP2.Name = (*source).Name + schemaFloatingIP = schemaFloatingIP2 + } + return schemaFloatingIP +} +func (c *converterImpl) SchemaFromISO(source *ISO) schema.ISO { + var schemaISO schema.ISO + if source != nil { + var schemaISO2 schema.ISO + schemaISO2.ID = (*source).ID + schemaISO2.Name = (*source).Name + schemaISO2.Description = (*source).Description + schemaISO2.Type = string((*source).Type) + if (*source).Architecture != nil { + xstring := string(*(*source).Architecture) + schemaISO2.Architecture = &xstring + } + schemaISO2.DeprecatableResource = c.hcloudDeprecatableResourceToSchemaDeprecatableResource((*source).DeprecatableResource) + schemaISO = schemaISO2 + } + return schemaISO +} +func (c *converterImpl) SchemaFromImage(source *Image) schema.Image { + var schemaImage schema.Image + if source != nil { + schemaImage = c.intSchemaFromImage((*source)) + } + return schemaImage +} +func (c *converterImpl) SchemaFromLoadBalancer(source *LoadBalancer) schema.LoadBalancer { + var schemaLoadBalancer schema.LoadBalancer + if source != nil { + var schemaLoadBalancer2 schema.LoadBalancer + schemaLoadBalancer2.ID = (*source).ID + schemaLoadBalancer2.Name = (*source).Name + schemaLoadBalancer2.PublicNet = c.hcloudLoadBalancerPublicNetToSchemaLoadBalancerPublicNet((*source).PublicNet) + if (*source).PrivateNet != nil { + schemaLoadBalancer2.PrivateNet = make([]schema.LoadBalancerPrivateNet, len((*source).PrivateNet)) + for i := 0; i < len((*source).PrivateNet); i++ { + schemaLoadBalancer2.PrivateNet[i] = c.hcloudLoadBalancerPrivateNetToSchemaLoadBalancerPrivateNet((*source).PrivateNet[i]) + } + } + schemaLoadBalancer2.Location = c.SchemaFromLocation((*source).Location) + schemaLoadBalancer2.LoadBalancerType = c.SchemaFromLoadBalancerType((*source).LoadBalancerType) + schemaLoadBalancer2.Protection = c.hcloudLoadBalancerProtectionToSchemaLoadBalancerProtection((*source).Protection) + schemaLoadBalancer2.Labels = (*source).Labels + schemaLoadBalancer2.Created = c.timeTimeToTimeTime((*source).Created) + if (*source).Services != nil { + schemaLoadBalancer2.Services = make([]schema.LoadBalancerService, len((*source).Services)) + for j := 0; j < len((*source).Services); j++ { + schemaLoadBalancer2.Services[j] = c.SchemaFromLoadBalancerService((*source).Services[j]) + } + } + if (*source).Targets != nil { + schemaLoadBalancer2.Targets = make([]schema.LoadBalancerTarget, len((*source).Targets)) + for k := 0; k < len((*source).Targets); k++ { + schemaLoadBalancer2.Targets[k] = c.SchemaFromLoadBalancerTarget((*source).Targets[k]) + } + } + schemaLoadBalancer2.Algorithm = c.hcloudLoadBalancerAlgorithmToSchemaLoadBalancerAlgorithm((*source).Algorithm) + schemaLoadBalancer2.IncludedTraffic = (*source).IncludedTraffic + schemaLoadBalancer2.OutgoingTraffic = mapZeroUint64ToNil((*source).OutgoingTraffic) + schemaLoadBalancer2.IngoingTraffic = mapZeroUint64ToNil((*source).IngoingTraffic) + schemaLoadBalancer = schemaLoadBalancer2 + } + return schemaLoadBalancer +} +func (c *converterImpl) SchemaFromLoadBalancerAddServiceOpts(source LoadBalancerAddServiceOpts) schema.LoadBalancerActionAddServiceRequest { + var schemaLoadBalancerActionAddServiceRequest schema.LoadBalancerActionAddServiceRequest + schemaLoadBalancerActionAddServiceRequest.Protocol = string(source.Protocol) + schemaLoadBalancerActionAddServiceRequest.ListenPort = source.ListenPort + schemaLoadBalancerActionAddServiceRequest.DestinationPort = source.DestinationPort + schemaLoadBalancerActionAddServiceRequest.Proxyprotocol = source.Proxyprotocol + schemaLoadBalancerActionAddServiceRequest.HTTP = c.pHcloudLoadBalancerAddServiceOptsHTTPToPSchemaLoadBalancerActionAddServiceRequestHTTP(source.HTTP) + schemaLoadBalancerActionAddServiceRequest.HealthCheck = c.pHcloudLoadBalancerAddServiceOptsHealthCheckToPSchemaLoadBalancerActionAddServiceRequestHealthCheck(source.HealthCheck) + return schemaLoadBalancerActionAddServiceRequest +} +func (c *converterImpl) SchemaFromLoadBalancerCreateOpts(source LoadBalancerCreateOpts) schema.LoadBalancerCreateRequest { + var schemaLoadBalancerCreateRequest schema.LoadBalancerCreateRequest + schemaLoadBalancerCreateRequest.Name = source.Name + schemaLoadBalancerCreateRequest.LoadBalancerType = c.pHcloudLoadBalancerTypeToSchemaIDOrName(source.LoadBalancerType) + schemaLoadBalancerCreateRequest.Algorithm = c.pHcloudLoadBalancerAlgorithmToPSchemaLoadBalancerCreateRequestAlgorithm(source.Algorithm) + schemaLoadBalancerCreateRequest.Location = c.pHcloudLocationToPString(source.Location) + schemaLoadBalancerCreateRequest.NetworkZone = stringPtrFromNetworkZone(source.NetworkZone) + schemaLoadBalancerCreateRequest.Labels = stringMapToStringMapPtr(source.Labels) + if source.Targets != nil { + schemaLoadBalancerCreateRequest.Targets = make([]schema.LoadBalancerCreateRequestTarget, len(source.Targets)) + for i := 0; i < len(source.Targets); i++ { + schemaLoadBalancerCreateRequest.Targets[i] = c.hcloudLoadBalancerCreateOptsTargetToSchemaLoadBalancerCreateRequestTarget(source.Targets[i]) + } + } + if source.Services != nil { + schemaLoadBalancerCreateRequest.Services = make([]schema.LoadBalancerCreateRequestService, len(source.Services)) + for j := 0; j < len(source.Services); j++ { + schemaLoadBalancerCreateRequest.Services[j] = c.hcloudLoadBalancerCreateOptsServiceToSchemaLoadBalancerCreateRequestService(source.Services[j]) + } + } + schemaLoadBalancerCreateRequest.PublicInterface = source.PublicInterface + schemaLoadBalancerCreateRequest.Network = c.pHcloudNetworkToPInt64(source.Network) + return schemaLoadBalancerCreateRequest +} +func (c *converterImpl) SchemaFromLoadBalancerCreateOptsTargetServer(source LoadBalancerCreateOptsTargetServer) schema.LoadBalancerCreateRequestTargetServer { + var schemaLoadBalancerCreateRequestTargetServer schema.LoadBalancerCreateRequestTargetServer + var pInt64 *int64 + if source.Server != nil { + pInt64 = &source.Server.ID + } + if pInt64 != nil { + schemaLoadBalancerCreateRequestTargetServer.ID = *pInt64 + } + return schemaLoadBalancerCreateRequestTargetServer +} +func (c *converterImpl) SchemaFromLoadBalancerServerTarget(source LoadBalancerTargetServer) schema.LoadBalancerTargetServer { + var schemaLoadBalancerTargetServer schema.LoadBalancerTargetServer + schemaLoadBalancerTargetServer.ID = c.pHcloudServerToInt64(source.Server) + return schemaLoadBalancerTargetServer +} +func (c *converterImpl) SchemaFromLoadBalancerService(source LoadBalancerService) schema.LoadBalancerService { + var schemaLoadBalancerService schema.LoadBalancerService + schemaLoadBalancerService.Protocol = string(source.Protocol) + schemaLoadBalancerService.ListenPort = source.ListenPort + schemaLoadBalancerService.DestinationPort = source.DestinationPort + schemaLoadBalancerService.Proxyprotocol = source.Proxyprotocol + schemaLoadBalancerService.HTTP = c.hcloudLoadBalancerServiceHTTPToPSchemaLoadBalancerServiceHTTP(source.HTTP) + schemaLoadBalancerService.HealthCheck = c.SchemaFromLoadBalancerServiceHealthCheck(source.HealthCheck) + return schemaLoadBalancerService +} +func (c *converterImpl) SchemaFromLoadBalancerServiceHealthCheck(source LoadBalancerServiceHealthCheck) *schema.LoadBalancerServiceHealthCheck { + var schemaLoadBalancerServiceHealthCheck schema.LoadBalancerServiceHealthCheck + schemaLoadBalancerServiceHealthCheck.Protocol = string(source.Protocol) + schemaLoadBalancerServiceHealthCheck.Port = source.Port + schemaLoadBalancerServiceHealthCheck.Interval = intSecondsFromDuration(source.Interval) + schemaLoadBalancerServiceHealthCheck.Timeout = intSecondsFromDuration(source.Timeout) + schemaLoadBalancerServiceHealthCheck.Retries = source.Retries + schemaLoadBalancerServiceHealthCheck.HTTP = c.pHcloudLoadBalancerServiceHealthCheckHTTPToPSchemaLoadBalancerServiceHealthCheckHTTP(source.HTTP) + return &schemaLoadBalancerServiceHealthCheck +} +func (c *converterImpl) SchemaFromLoadBalancerTarget(source LoadBalancerTarget) schema.LoadBalancerTarget { + var schemaLoadBalancerTarget schema.LoadBalancerTarget + schemaLoadBalancerTarget.Type = string(source.Type) + schemaLoadBalancerTarget.Server = c.pHcloudLoadBalancerTargetServerToPSchemaLoadBalancerTargetServer(source.Server) + schemaLoadBalancerTarget.LabelSelector = c.pHcloudLoadBalancerTargetLabelSelectorToPSchemaLoadBalancerTargetLabelSelector(source.LabelSelector) + schemaLoadBalancerTarget.IP = c.pHcloudLoadBalancerTargetIPToPSchemaLoadBalancerTargetIP(source.IP) + if source.HealthStatus != nil { + schemaLoadBalancerTarget.HealthStatus = make([]schema.LoadBalancerTargetHealthStatus, len(source.HealthStatus)) + for i := 0; i < len(source.HealthStatus); i++ { + schemaLoadBalancerTarget.HealthStatus[i] = c.SchemaFromLoadBalancerTargetHealthStatus(source.HealthStatus[i]) + } + } + schemaLoadBalancerTarget.UsePrivateIP = source.UsePrivateIP + if source.Targets != nil { + schemaLoadBalancerTarget.Targets = make([]schema.LoadBalancerTarget, len(source.Targets)) + for j := 0; j < len(source.Targets); j++ { + schemaLoadBalancerTarget.Targets[j] = c.SchemaFromLoadBalancerTarget(source.Targets[j]) + } + } + return schemaLoadBalancerTarget +} +func (c *converterImpl) SchemaFromLoadBalancerTargetHealthStatus(source LoadBalancerTargetHealthStatus) schema.LoadBalancerTargetHealthStatus { + var schemaLoadBalancerTargetHealthStatus schema.LoadBalancerTargetHealthStatus + schemaLoadBalancerTargetHealthStatus.ListenPort = source.ListenPort + schemaLoadBalancerTargetHealthStatus.Status = string(source.Status) + return schemaLoadBalancerTargetHealthStatus +} +func (c *converterImpl) SchemaFromLoadBalancerType(source *LoadBalancerType) schema.LoadBalancerType { + var schemaLoadBalancerType schema.LoadBalancerType + if source != nil { + var schemaLoadBalancerType2 schema.LoadBalancerType + schemaLoadBalancerType2.ID = (*source).ID + schemaLoadBalancerType2.Name = (*source).Name + schemaLoadBalancerType2.Description = (*source).Description + schemaLoadBalancerType2.MaxConnections = (*source).MaxConnections + schemaLoadBalancerType2.MaxServices = (*source).MaxServices + schemaLoadBalancerType2.MaxTargets = (*source).MaxTargets + schemaLoadBalancerType2.MaxAssignedCertificates = (*source).MaxAssignedCertificates + if (*source).Pricings != nil { + schemaLoadBalancerType2.Prices = make([]schema.PricingLoadBalancerTypePrice, len((*source).Pricings)) + for i := 0; i < len((*source).Pricings); i++ { + schemaLoadBalancerType2.Prices[i] = c.SchemaFromLoadBalancerTypeLocationPricing((*source).Pricings[i]) + } + } + schemaLoadBalancerType2.Deprecated = (*source).Deprecated + schemaLoadBalancerType = schemaLoadBalancerType2 + } + return schemaLoadBalancerType +} +func (c *converterImpl) SchemaFromLoadBalancerTypeLocationPricing(source LoadBalancerTypeLocationPricing) schema.PricingLoadBalancerTypePrice { + var schemaPricingLoadBalancerTypePrice schema.PricingLoadBalancerTypePrice + schemaPricingLoadBalancerTypePrice.Location = c.pHcloudLocationToString(source.Location) + schemaPricingLoadBalancerTypePrice.PriceHourly = c.hcloudPriceToSchemaPrice(source.Hourly) + schemaPricingLoadBalancerTypePrice.PriceMonthly = c.hcloudPriceToSchemaPrice(source.Monthly) + schemaPricingLoadBalancerTypePrice.IncludedTraffic = source.IncludedTraffic + schemaPricingLoadBalancerTypePrice.PricePerTBTraffic = c.hcloudPriceToSchemaPrice(source.PerTBTraffic) + return schemaPricingLoadBalancerTypePrice +} +func (c *converterImpl) SchemaFromLoadBalancerUpdateServiceOpts(source LoadBalancerUpdateServiceOpts) schema.LoadBalancerActionUpdateServiceRequest { + var schemaLoadBalancerActionUpdateServiceRequest schema.LoadBalancerActionUpdateServiceRequest + schemaLoadBalancerActionUpdateServiceRequest.Protocol = stringPtrFromLoadBalancerServiceProtocol(source.Protocol) + schemaLoadBalancerActionUpdateServiceRequest.DestinationPort = source.DestinationPort + schemaLoadBalancerActionUpdateServiceRequest.Proxyprotocol = source.Proxyprotocol + schemaLoadBalancerActionUpdateServiceRequest.HTTP = c.pHcloudLoadBalancerUpdateServiceOptsHTTPToPSchemaLoadBalancerActionUpdateServiceRequestHTTP(source.HTTP) + schemaLoadBalancerActionUpdateServiceRequest.HealthCheck = c.pHcloudLoadBalancerUpdateServiceOptsHealthCheckToPSchemaLoadBalancerActionUpdateServiceRequestHealthCheck(source.HealthCheck) + return schemaLoadBalancerActionUpdateServiceRequest +} +func (c *converterImpl) SchemaFromLocation(source *Location) schema.Location { + var schemaLocation schema.Location + if source != nil { + var schemaLocation2 schema.Location + schemaLocation2.ID = (*source).ID + schemaLocation2.Name = (*source).Name + schemaLocation2.Description = (*source).Description + schemaLocation2.Country = (*source).Country + schemaLocation2.City = (*source).City + schemaLocation2.Latitude = (*source).Latitude + schemaLocation2.Longitude = (*source).Longitude + schemaLocation2.NetworkZone = string((*source).NetworkZone) + schemaLocation = schemaLocation2 + } + return schemaLocation +} +func (c *converterImpl) SchemaFromNetwork(source *Network) schema.Network { + var schemaNetwork schema.Network + if source != nil { + var schemaNetwork2 schema.Network + schemaNetwork2.ID = (*source).ID + schemaNetwork2.Name = (*source).Name + schemaNetwork2.Created = c.timeTimeToTimeTime((*source).Created) + schemaNetwork2.IPRange = c.pNetIPNetToString((*source).IPRange) + if (*source).Subnets != nil { + schemaNetwork2.Subnets = make([]schema.NetworkSubnet, len((*source).Subnets)) + for i := 0; i < len((*source).Subnets); i++ { + schemaNetwork2.Subnets[i] = c.SchemaFromNetworkSubnet((*source).Subnets[i]) + } + } + if (*source).Routes != nil { + schemaNetwork2.Routes = make([]schema.NetworkRoute, len((*source).Routes)) + for j := 0; j < len((*source).Routes); j++ { + schemaNetwork2.Routes[j] = c.SchemaFromNetworkRoute((*source).Routes[j]) + } + } + if (*source).Servers != nil { + schemaNetwork2.Servers = make([]int64, len((*source).Servers)) + for k := 0; k < len((*source).Servers); k++ { + schemaNetwork2.Servers[k] = c.pHcloudServerToInt64((*source).Servers[k]) + } + } + if (*source).LoadBalancers != nil { + schemaNetwork2.LoadBalancers = make([]int64, len((*source).LoadBalancers)) + for l := 0; l < len((*source).LoadBalancers); l++ { + schemaNetwork2.LoadBalancers[l] = c.pHcloudLoadBalancerToInt64((*source).LoadBalancers[l]) + } + } + schemaNetwork2.Protection = c.hcloudNetworkProtectionToSchemaNetworkProtection((*source).Protection) + schemaNetwork2.Labels = (*source).Labels + schemaNetwork2.ExposeRoutesToVSwitch = (*source).ExposeRoutesToVSwitch + schemaNetwork = schemaNetwork2 + } + return schemaNetwork +} +func (c *converterImpl) SchemaFromNetworkRoute(source NetworkRoute) schema.NetworkRoute { + var schemaNetworkRoute schema.NetworkRoute + schemaNetworkRoute.Destination = c.pNetIPNetToString(source.Destination) + schemaNetworkRoute.Gateway = stringFromIP(source.Gateway) + return schemaNetworkRoute +} +func (c *converterImpl) SchemaFromNetworkSubnet(source NetworkSubnet) schema.NetworkSubnet { + var schemaNetworkSubnet schema.NetworkSubnet + schemaNetworkSubnet.Type = string(source.Type) + schemaNetworkSubnet.IPRange = c.pNetIPNetToString(source.IPRange) + schemaNetworkSubnet.NetworkZone = string(source.NetworkZone) + schemaNetworkSubnet.Gateway = stringFromIP(source.Gateway) + schemaNetworkSubnet.VSwitchID = source.VSwitchID + return schemaNetworkSubnet +} +func (c *converterImpl) SchemaFromPagination(source Pagination) schema.MetaPagination { + var schemaMetaPagination schema.MetaPagination + schemaMetaPagination.Page = source.Page + schemaMetaPagination.PerPage = source.PerPage + schemaMetaPagination.PreviousPage = source.PreviousPage + schemaMetaPagination.NextPage = source.NextPage + schemaMetaPagination.LastPage = source.LastPage + schemaMetaPagination.TotalEntries = source.TotalEntries + return schemaMetaPagination +} +func (c *converterImpl) SchemaFromPlacementGroup(source *PlacementGroup) schema.PlacementGroup { + var schemaPlacementGroup schema.PlacementGroup + if source != nil { + var schemaPlacementGroup2 schema.PlacementGroup + schemaPlacementGroup2.ID = (*source).ID + schemaPlacementGroup2.Name = (*source).Name + schemaPlacementGroup2.Labels = (*source).Labels + schemaPlacementGroup2.Created = c.timeTimeToTimeTime((*source).Created) + schemaPlacementGroup2.Servers = (*source).Servers + schemaPlacementGroup2.Type = string((*source).Type) + schemaPlacementGroup = schemaPlacementGroup2 + } + return schemaPlacementGroup +} +func (c *converterImpl) SchemaFromPlacementGroupCreateOpts(source PlacementGroupCreateOpts) schema.PlacementGroupCreateRequest { + var schemaPlacementGroupCreateRequest schema.PlacementGroupCreateRequest + schemaPlacementGroupCreateRequest.Name = source.Name + schemaPlacementGroupCreateRequest.Labels = stringMapToStringMapPtr(source.Labels) + schemaPlacementGroupCreateRequest.Type = string(source.Type) + return schemaPlacementGroupCreateRequest +} +func (c *converterImpl) SchemaFromPricing(source Pricing) schema.Pricing { + var schemaPricing schema.Pricing + schemaPricing.Currency = source.Image.PerGBMonth.Currency + schemaPricing.VATRate = source.Image.PerGBMonth.VATRate + schemaPricing.Image = c.schemaFromImagePricing(source.Image) + schemaPricing.FloatingIP = c.schemaFromFloatingIPPricing(source.FloatingIP) + if source.FloatingIPs != nil { + schemaPricing.FloatingIPs = make([]schema.PricingFloatingIPType, len(source.FloatingIPs)) + for i := 0; i < len(source.FloatingIPs); i++ { + schemaPricing.FloatingIPs[i] = c.schemaFromFloatingIPTypePricing(source.FloatingIPs[i]) + } + } + if source.PrimaryIPs != nil { + schemaPricing.PrimaryIPs = make([]schema.PricingPrimaryIP, len(source.PrimaryIPs)) + for j := 0; j < len(source.PrimaryIPs); j++ { + schemaPricing.PrimaryIPs[j] = c.schemaFromPrimaryIPPricing(source.PrimaryIPs[j]) + } + } + schemaPricing.Traffic = c.schemaFromTrafficPricing(source.Traffic) + schemaPricing.ServerBackup = c.hcloudServerBackupPricingToSchemaPricingServerBackup(source.ServerBackup) + if source.ServerTypes != nil { + schemaPricing.ServerTypes = make([]schema.PricingServerType, len(source.ServerTypes)) + for k := 0; k < len(source.ServerTypes); k++ { + schemaPricing.ServerTypes[k] = c.schemaFromServerTypePricing(source.ServerTypes[k]) + } + } + if source.LoadBalancerTypes != nil { + schemaPricing.LoadBalancerTypes = make([]schema.PricingLoadBalancerType, len(source.LoadBalancerTypes)) + for l := 0; l < len(source.LoadBalancerTypes); l++ { + schemaPricing.LoadBalancerTypes[l] = c.schemaFromLoadBalancerTypePricing(source.LoadBalancerTypes[l]) + } + } + schemaPricing.Volume = c.schemaFromVolumePricing(source.Volume) + return schemaPricing +} +func (c *converterImpl) SchemaFromPrimaryIP(source *PrimaryIP) schema.PrimaryIP { + var schemaPrimaryIP schema.PrimaryIP + if source != nil { + var schemaPrimaryIP2 schema.PrimaryIP + schemaPrimaryIP2.ID = (*source).ID + schemaPrimaryIP2.IP = primaryIPToIPString((*source)) + schemaPrimaryIP2.Labels = (*source).Labels + schemaPrimaryIP2.Name = (*source).Name + schemaPrimaryIP2.Type = string((*source).Type) + schemaPrimaryIP2.Protection = c.hcloudPrimaryIPProtectionToSchemaPrimaryIPProtection((*source).Protection) + schemaPrimaryIP2.DNSPtr = primaryIPDNSPtrSchemaFromMap((*source).DNSPtr) + schemaPrimaryIP2.AssigneeID = mapZeroInt64ToNil((*source).AssigneeID) + schemaPrimaryIP2.AssigneeType = (*source).AssigneeType + schemaPrimaryIP2.AutoDelete = (*source).AutoDelete + schemaPrimaryIP2.Blocked = (*source).Blocked + schemaPrimaryIP2.Created = c.timeTimeToTimeTime((*source).Created) + schemaPrimaryIP2.Datacenter = c.SchemaFromDatacenter((*source).Datacenter) + schemaPrimaryIP = schemaPrimaryIP2 + } + return schemaPrimaryIP +} +func (c *converterImpl) SchemaFromPrimaryIPAssignOpts(source PrimaryIPAssignOpts) schema.PrimaryIPActionAssignRequest { + var schemaPrimaryIPActionAssignRequest schema.PrimaryIPActionAssignRequest + schemaPrimaryIPActionAssignRequest.AssigneeID = source.AssigneeID + schemaPrimaryIPActionAssignRequest.AssigneeType = source.AssigneeType + return schemaPrimaryIPActionAssignRequest +} +func (c *converterImpl) SchemaFromPrimaryIPChangeDNSPtrOpts(source PrimaryIPChangeDNSPtrOpts) schema.PrimaryIPActionChangeDNSPtrRequest { + var schemaPrimaryIPActionChangeDNSPtrRequest schema.PrimaryIPActionChangeDNSPtrRequest + schemaPrimaryIPActionChangeDNSPtrRequest.IP = source.IP + pString := source.DNSPtr + schemaPrimaryIPActionChangeDNSPtrRequest.DNSPtr = &pString + return schemaPrimaryIPActionChangeDNSPtrRequest +} +func (c *converterImpl) SchemaFromPrimaryIPChangeProtectionOpts(source PrimaryIPChangeProtectionOpts) schema.PrimaryIPActionChangeProtectionRequest { + var schemaPrimaryIPActionChangeProtectionRequest schema.PrimaryIPActionChangeProtectionRequest + schemaPrimaryIPActionChangeProtectionRequest.Delete = source.Delete + return schemaPrimaryIPActionChangeProtectionRequest +} +func (c *converterImpl) SchemaFromPrimaryIPCreateOpts(source PrimaryIPCreateOpts) schema.PrimaryIPCreateRequest { + var schemaPrimaryIPCreateRequest schema.PrimaryIPCreateRequest + schemaPrimaryIPCreateRequest.Name = source.Name + schemaPrimaryIPCreateRequest.Type = string(source.Type) + schemaPrimaryIPCreateRequest.AssigneeType = source.AssigneeType + schemaPrimaryIPCreateRequest.AssigneeID = source.AssigneeID + schemaPrimaryIPCreateRequest.Labels = source.Labels + schemaPrimaryIPCreateRequest.AutoDelete = source.AutoDelete + schemaPrimaryIPCreateRequest.Datacenter = source.Datacenter + return schemaPrimaryIPCreateRequest +} +func (c *converterImpl) SchemaFromPrimaryIPUpdateOpts(source PrimaryIPUpdateOpts) schema.PrimaryIPUpdateRequest { + var schemaPrimaryIPUpdateRequest schema.PrimaryIPUpdateRequest + schemaPrimaryIPUpdateRequest.Name = source.Name + if source.Labels != nil { + schemaPrimaryIPUpdateRequest.Labels = (*source.Labels) + } + schemaPrimaryIPUpdateRequest.AutoDelete = source.AutoDelete + return schemaPrimaryIPUpdateRequest +} +func (c *converterImpl) SchemaFromSSHKey(source *SSHKey) schema.SSHKey { + var schemaSSHKey schema.SSHKey + if source != nil { + var schemaSSHKey2 schema.SSHKey + schemaSSHKey2.ID = (*source).ID + schemaSSHKey2.Name = (*source).Name + schemaSSHKey2.Fingerprint = (*source).Fingerprint + schemaSSHKey2.PublicKey = (*source).PublicKey + schemaSSHKey2.Labels = (*source).Labels + schemaSSHKey2.Created = c.timeTimeToTimeTime((*source).Created) + schemaSSHKey = schemaSSHKey2 + } + return schemaSSHKey +} +func (c *converterImpl) SchemaFromServer(source *Server) schema.Server { + var schemaServer schema.Server + if source != nil { + var schemaServer2 schema.Server + schemaServer2.ID = (*source).ID + schemaServer2.Name = (*source).Name + schemaServer2.Status = string((*source).Status) + schemaServer2.Created = c.timeTimeToTimeTime((*source).Created) + schemaServer2.PublicNet = c.SchemaFromServerPublicNet((*source).PublicNet) + if (*source).PrivateNet != nil { + schemaServer2.PrivateNet = make([]schema.ServerPrivateNet, len((*source).PrivateNet)) + for i := 0; i < len((*source).PrivateNet); i++ { + schemaServer2.PrivateNet[i] = c.SchemaFromServerPrivateNet((*source).PrivateNet[i]) + } + } + schemaServer2.ServerType = c.SchemaFromServerType((*source).ServerType) + schemaServer2.IncludedTraffic = (*source).IncludedTraffic + schemaServer2.OutgoingTraffic = mapZeroUint64ToNil((*source).OutgoingTraffic) + schemaServer2.IngoingTraffic = mapZeroUint64ToNil((*source).IngoingTraffic) + schemaServer2.BackupWindow = mapEmptyStringToNil((*source).BackupWindow) + schemaServer2.RescueEnabled = (*source).RescueEnabled + schemaServer2.ISO = c.pHcloudISOToPSchemaISO((*source).ISO) + schemaServer2.Locked = (*source).Locked + schemaServer2.Datacenter = c.SchemaFromDatacenter((*source).Datacenter) + schemaServer2.Image = c.pHcloudImageToPSchemaImage((*source).Image) + schemaServer2.Protection = c.hcloudServerProtectionToSchemaServerProtection((*source).Protection) + schemaServer2.Labels = (*source).Labels + if (*source).Volumes != nil { + schemaServer2.Volumes = make([]int64, len((*source).Volumes)) + for j := 0; j < len((*source).Volumes); j++ { + schemaServer2.Volumes[j] = int64FromVolume((*source).Volumes[j]) + } + } + schemaServer2.PrimaryDiskSize = (*source).PrimaryDiskSize + schemaServer2.PlacementGroup = c.pHcloudPlacementGroupToPSchemaPlacementGroup((*source).PlacementGroup) + if (*source).LoadBalancers != nil { + schemaServer2.LoadBalancers = make([]int64, len((*source).LoadBalancers)) + for k := 0; k < len((*source).LoadBalancers); k++ { + schemaServer2.LoadBalancers[k] = c.pHcloudLoadBalancerToInt64((*source).LoadBalancers[k]) + } + } + schemaServer = schemaServer2 + } + return schemaServer +} +func (c *converterImpl) SchemaFromServerPrivateNet(source ServerPrivateNet) schema.ServerPrivateNet { + var schemaServerPrivateNet schema.ServerPrivateNet + schemaServerPrivateNet.Network = c.pHcloudNetworkToInt64(source.Network) + schemaServerPrivateNet.IP = stringFromIP(source.IP) + if source.Aliases != nil { + schemaServerPrivateNet.AliasIPs = make([]string, len(source.Aliases)) + for i := 0; i < len(source.Aliases); i++ { + schemaServerPrivateNet.AliasIPs[i] = stringFromIP(source.Aliases[i]) + } + } + schemaServerPrivateNet.MACAddress = source.MACAddress + return schemaServerPrivateNet +} +func (c *converterImpl) SchemaFromServerPublicNet(source ServerPublicNet) schema.ServerPublicNet { + var schemaServerPublicNet schema.ServerPublicNet + schemaServerPublicNet.IPv4 = c.SchemaFromServerPublicNetIPv4(source.IPv4) + schemaServerPublicNet.IPv6 = c.SchemaFromServerPublicNetIPv6(source.IPv6) + if source.FloatingIPs != nil { + schemaServerPublicNet.FloatingIPs = make([]int64, len(source.FloatingIPs)) + for i := 0; i < len(source.FloatingIPs); i++ { + schemaServerPublicNet.FloatingIPs[i] = int64FromFloatingIP(source.FloatingIPs[i]) + } + } + if source.Firewalls != nil { + schemaServerPublicNet.Firewalls = make([]schema.ServerFirewall, len(source.Firewalls)) + for j := 0; j < len(source.Firewalls); j++ { + schemaServerPublicNet.Firewalls[j] = serverFirewallSchemaFromFirewallStatus(source.Firewalls[j]) + } + } + return schemaServerPublicNet +} +func (c *converterImpl) SchemaFromServerPublicNetIPv4(source ServerPublicNetIPv4) schema.ServerPublicNetIPv4 { + var schemaServerPublicNetIPv4 schema.ServerPublicNetIPv4 + schemaServerPublicNetIPv4.ID = source.ID + schemaServerPublicNetIPv4.IP = stringFromIP(source.IP) + schemaServerPublicNetIPv4.Blocked = source.Blocked + schemaServerPublicNetIPv4.DNSPtr = source.DNSPtr + return schemaServerPublicNetIPv4 +} +func (c *converterImpl) SchemaFromServerPublicNetIPv6(source ServerPublicNetIPv6) schema.ServerPublicNetIPv6 { + var schemaServerPublicNetIPv6 schema.ServerPublicNetIPv6 + schemaServerPublicNetIPv6.ID = source.ID + schemaServerPublicNetIPv6.IP = c.pNetIPNetToString(source.Network) + schemaServerPublicNetIPv6.Blocked = source.Blocked + schemaServerPublicNetIPv6.DNSPtr = serverPublicNetIPv6DNSPtrSchemaFromMap(source.DNSPtr) + return schemaServerPublicNetIPv6 +} +func (c *converterImpl) SchemaFromServerType(source *ServerType) schema.ServerType { + var schemaServerType schema.ServerType + if source != nil { + var schemaServerType2 schema.ServerType + schemaServerType2.ID = (*source).ID + schemaServerType2.Name = (*source).Name + schemaServerType2.Description = (*source).Description + schemaServerType2.Cores = (*source).Cores + schemaServerType2.Memory = (*source).Memory + schemaServerType2.Disk = (*source).Disk + schemaServerType2.StorageType = string((*source).StorageType) + schemaServerType2.CPUType = string((*source).CPUType) + schemaServerType2.Architecture = string((*source).Architecture) + schemaServerType2.IncludedTraffic = (*source).IncludedTraffic + if (*source).Pricings != nil { + schemaServerType2.Prices = make([]schema.PricingServerTypePrice, len((*source).Pricings)) + for i := 0; i < len((*source).Pricings); i++ { + schemaServerType2.Prices[i] = c.schemaFromServerTypeLocationPricing((*source).Pricings[i]) + } + } + schemaServerType2.Deprecated = isDeprecationNotNil((*source).DeprecatableResource.Deprecation) + schemaServerType2.DeprecatableResource = c.hcloudDeprecatableResourceToSchemaDeprecatableResource((*source).DeprecatableResource) + schemaServerType = schemaServerType2 + } + return schemaServerType +} +func (c *converterImpl) SchemaFromVolume(source *Volume) schema.Volume { + var schemaVolume schema.Volume + if source != nil { + var schemaVolume2 schema.Volume + schemaVolume2.ID = (*source).ID + schemaVolume2.Name = (*source).Name + schemaVolume2.Server = c.pHcloudServerToPInt64((*source).Server) + schemaVolume2.Status = string((*source).Status) + schemaVolume2.Location = c.SchemaFromLocation((*source).Location) + schemaVolume2.Size = (*source).Size + schemaVolume2.Format = (*source).Format + schemaVolume2.Protection = c.hcloudVolumeProtectionToSchemaVolumeProtection((*source).Protection) + schemaVolume2.Labels = (*source).Labels + schemaVolume2.LinuxDevice = (*source).LinuxDevice + schemaVolume2.Created = c.timeTimeToTimeTime((*source).Created) + schemaVolume = schemaVolume2 + } + return schemaVolume +} +func (c *converterImpl) ServerFromSchema(source schema.Server) *Server { + var hcloudServer Server + hcloudServer.ID = source.ID + hcloudServer.Name = source.Name + hcloudServer.Status = ServerStatus(source.Status) + hcloudServer.Created = c.timeTimeToTimeTime(source.Created) + hcloudServer.PublicNet = c.ServerPublicNetFromSchema(source.PublicNet) + if source.PrivateNet != nil { + hcloudServer.PrivateNet = make([]ServerPrivateNet, len(source.PrivateNet)) + for i := 0; i < len(source.PrivateNet); i++ { + hcloudServer.PrivateNet[i] = c.ServerPrivateNetFromSchema(source.PrivateNet[i]) + } + } + hcloudServer.ServerType = c.ServerTypeFromSchema(source.ServerType) + hcloudServer.Datacenter = c.DatacenterFromSchema(source.Datacenter) + hcloudServer.IncludedTraffic = source.IncludedTraffic + if source.OutgoingTraffic != nil { + hcloudServer.OutgoingTraffic = *source.OutgoingTraffic + } + if source.IngoingTraffic != nil { + hcloudServer.IngoingTraffic = *source.IngoingTraffic + } + if source.BackupWindow != nil { + hcloudServer.BackupWindow = *source.BackupWindow + } + hcloudServer.RescueEnabled = source.RescueEnabled + hcloudServer.Locked = source.Locked + hcloudServer.ISO = c.pSchemaISOToPHcloudISO(source.ISO) + hcloudServer.Image = c.pSchemaImageToPHcloudImage(source.Image) + hcloudServer.Protection = c.schemaServerProtectionToHcloudServerProtection(source.Protection) + hcloudServer.Labels = source.Labels + if source.Volumes != nil { + hcloudServer.Volumes = make([]*Volume, len(source.Volumes)) + for j := 0; j < len(source.Volumes); j++ { + hcloudServer.Volumes[j] = volumeFromInt64(source.Volumes[j]) + } + } + hcloudServer.PrimaryDiskSize = source.PrimaryDiskSize + hcloudServer.PlacementGroup = c.pSchemaPlacementGroupToPHcloudPlacementGroup(source.PlacementGroup) + if source.LoadBalancers != nil { + hcloudServer.LoadBalancers = make([]*LoadBalancer, len(source.LoadBalancers)) + for k := 0; k < len(source.LoadBalancers); k++ { + hcloudLoadBalancer := loadBalancerFromInt64(source.LoadBalancers[k]) + hcloudServer.LoadBalancers[k] = &hcloudLoadBalancer + } + } + return &hcloudServer +} +func (c *converterImpl) ServerMetricsFromSchema(source *schema.ServerGetMetricsResponse) (*ServerMetrics, error) { + var pHcloudServerMetrics *ServerMetrics + if source != nil { + var hcloudServerMetrics ServerMetrics + hcloudServerMetrics.Start = c.timeTimeToTimeTime((*source).Metrics.Start) + hcloudServerMetrics.End = c.timeTimeToTimeTime((*source).Metrics.End) + hcloudServerMetrics.Step = (*source).Metrics.Step + if (*source).Metrics.TimeSeries != nil { + hcloudServerMetrics.TimeSeries = make(map[string][]ServerMetricsValue, len((*source).Metrics.TimeSeries)) + for key, value := range (*source).Metrics.TimeSeries { + hcloudServerMetricsValueList, err := serverMetricsTimeSeriesFromSchema(value) + if err != nil { + return nil, err + } + hcloudServerMetrics.TimeSeries[key] = hcloudServerMetricsValueList + } + } + pHcloudServerMetrics = &hcloudServerMetrics + } + return pHcloudServerMetrics, nil +} +func (c *converterImpl) ServerPrivateNetFromSchema(source schema.ServerPrivateNet) ServerPrivateNet { + var hcloudServerPrivateNet ServerPrivateNet + hcloudNetwork := networkFromInt64(source.Network) + hcloudServerPrivateNet.Network = &hcloudNetwork + hcloudServerPrivateNet.IP = ipFromString(source.IP) + if source.AliasIPs != nil { + hcloudServerPrivateNet.Aliases = make([]net.IP, len(source.AliasIPs)) + for i := 0; i < len(source.AliasIPs); i++ { + hcloudServerPrivateNet.Aliases[i] = ipFromString(source.AliasIPs[i]) + } + } + hcloudServerPrivateNet.MACAddress = source.MACAddress + return hcloudServerPrivateNet +} +func (c *converterImpl) ServerPublicNetFromSchema(source schema.ServerPublicNet) ServerPublicNet { + var hcloudServerPublicNet ServerPublicNet + hcloudServerPublicNet.IPv4 = c.ServerPublicNetIPv4FromSchema(source.IPv4) + hcloudServerPublicNet.IPv6 = c.ServerPublicNetIPv6FromSchema(source.IPv6) + if source.FloatingIPs != nil { + hcloudServerPublicNet.FloatingIPs = make([]*FloatingIP, len(source.FloatingIPs)) + for i := 0; i < len(source.FloatingIPs); i++ { + hcloudServerPublicNet.FloatingIPs[i] = floatingIPFromInt64(source.FloatingIPs[i]) + } + } + if source.Firewalls != nil { + hcloudServerPublicNet.Firewalls = make([]*ServerFirewallStatus, len(source.Firewalls)) + for j := 0; j < len(source.Firewalls); j++ { + hcloudServerPublicNet.Firewalls[j] = firewallStatusFromSchemaServerFirewall(source.Firewalls[j]) + } + } + return hcloudServerPublicNet +} +func (c *converterImpl) ServerPublicNetIPv4FromSchema(source schema.ServerPublicNetIPv4) ServerPublicNetIPv4 { + var hcloudServerPublicNetIPv4 ServerPublicNetIPv4 + hcloudServerPublicNetIPv4.ID = source.ID + hcloudServerPublicNetIPv4.IP = ipFromString(source.IP) + hcloudServerPublicNetIPv4.Blocked = source.Blocked + hcloudServerPublicNetIPv4.DNSPtr = source.DNSPtr + return hcloudServerPublicNetIPv4 +} +func (c *converterImpl) ServerPublicNetIPv6FromSchema(source schema.ServerPublicNetIPv6) ServerPublicNetIPv6 { + var hcloudServerPublicNetIPv6 ServerPublicNetIPv6 + hcloudServerPublicNetIPv6.ID = source.ID + hcloudServerPublicNetIPv6.IP = ipFromServerPublicNetIPv6Schema(source) + hcloudServerPublicNetIPv6.Network = ipNetFromServerPublicNetIPv6Schema(source) + hcloudServerPublicNetIPv6.Blocked = source.Blocked + hcloudServerPublicNetIPv6.DNSPtr = mapFromServerPublicNetIPv6DNSPtrSchema(source.DNSPtr) + return hcloudServerPublicNetIPv6 +} +func (c *converterImpl) ServerTypeFromSchema(source schema.ServerType) *ServerType { + var hcloudServerType ServerType + hcloudServerType.ID = source.ID + hcloudServerType.Name = source.Name + hcloudServerType.Description = source.Description + hcloudServerType.Cores = source.Cores + hcloudServerType.Memory = source.Memory + hcloudServerType.Disk = source.Disk + hcloudServerType.StorageType = StorageType(source.StorageType) + hcloudServerType.CPUType = CPUType(source.CPUType) + hcloudServerType.Architecture = Architecture(source.Architecture) + hcloudServerType.IncludedTraffic = source.IncludedTraffic + if source.Prices != nil { + hcloudServerType.Pricings = make([]ServerTypeLocationPricing, len(source.Prices)) + for i := 0; i < len(source.Prices); i++ { + hcloudServerType.Pricings[i] = c.serverTypePricingFromSchema(source.Prices[i]) + } + } + hcloudServerType.DeprecatableResource = c.schemaDeprecatableResourceToHcloudDeprecatableResource(source.DeprecatableResource) + return &hcloudServerType +} +func (c *converterImpl) VolumeFromSchema(source schema.Volume) *Volume { + var hcloudVolume Volume + hcloudVolume.ID = source.ID + hcloudVolume.Name = source.Name + hcloudVolume.Status = VolumeStatus(source.Status) + if source.Server != nil { + hcloudServer := serverFromInt64(*source.Server) + hcloudVolume.Server = &hcloudServer + } + hcloudVolume.Location = c.LocationFromSchema(source.Location) + hcloudVolume.Size = source.Size + hcloudVolume.Format = source.Format + hcloudVolume.Protection = c.schemaVolumeProtectionToHcloudVolumeProtection(source.Protection) + hcloudVolume.Labels = source.Labels + hcloudVolume.LinuxDevice = source.LinuxDevice + hcloudVolume.Created = c.timeTimeToTimeTime(source.Created) + return &hcloudVolume +} +func (c *converterImpl) hcloudCertificateStatusTypeToString(source CertificateStatusType) string { + return string(source) +} +func (c *converterImpl) hcloudCertificateUsedByRefToSchemaCertificateUsedByRef(source CertificateUsedByRef) schema.CertificateUsedByRef { + var schemaCertificateUsedByRef schema.CertificateUsedByRef + schemaCertificateUsedByRef.ID = source.ID + schemaCertificateUsedByRef.Type = string(source.Type) + return schemaCertificateUsedByRef +} +func (c *converterImpl) hcloudDatacenterServerTypesToSchemaDatacenterServerTypes(source DatacenterServerTypes) schema.DatacenterServerTypes { + var schemaDatacenterServerTypes schema.DatacenterServerTypes + if source.Supported != nil { + schemaDatacenterServerTypes.Supported = make([]int64, len(source.Supported)) + for i := 0; i < len(source.Supported); i++ { + schemaDatacenterServerTypes.Supported[i] = int64FromServerType(source.Supported[i]) + } + } + if source.AvailableForMigration != nil { + schemaDatacenterServerTypes.AvailableForMigration = make([]int64, len(source.AvailableForMigration)) + for j := 0; j < len(source.AvailableForMigration); j++ { + schemaDatacenterServerTypes.AvailableForMigration[j] = int64FromServerType(source.AvailableForMigration[j]) + } + } + if source.Available != nil { + schemaDatacenterServerTypes.Available = make([]int64, len(source.Available)) + for k := 0; k < len(source.Available); k++ { + schemaDatacenterServerTypes.Available[k] = int64FromServerType(source.Available[k]) + } + } + return schemaDatacenterServerTypes +} +func (c *converterImpl) hcloudDeprecatableResourceToSchemaDeprecatableResource(source DeprecatableResource) schema.DeprecatableResource { + var schemaDeprecatableResource schema.DeprecatableResource + schemaDeprecatableResource.Deprecation = c.SchemaFromDeprecation(source.Deprecation) + return schemaDeprecatableResource +} +func (c *converterImpl) hcloudFirewallRuleToSchemaFirewallRule(source FirewallRule) schema.FirewallRule { + var schemaFirewallRule schema.FirewallRule + schemaFirewallRule.Direction = string(source.Direction) + if source.SourceIPs != nil { + schemaFirewallRule.SourceIPs = make([]string, len(source.SourceIPs)) + for i := 0; i < len(source.SourceIPs); i++ { + schemaFirewallRule.SourceIPs[i] = stringFromIPNet(source.SourceIPs[i]) + } + } + if source.DestinationIPs != nil { + schemaFirewallRule.DestinationIPs = make([]string, len(source.DestinationIPs)) + for j := 0; j < len(source.DestinationIPs); j++ { + schemaFirewallRule.DestinationIPs[j] = stringFromIPNet(source.DestinationIPs[j]) + } + } + schemaFirewallRule.Protocol = string(source.Protocol) + schemaFirewallRule.Port = source.Port + schemaFirewallRule.Description = source.Description + return schemaFirewallRule +} +func (c *converterImpl) hcloudFirewallRuleToSchemaFirewallRuleRequest(source FirewallRule) schema.FirewallRuleRequest { + var schemaFirewallRuleRequest schema.FirewallRuleRequest + schemaFirewallRuleRequest.Direction = string(source.Direction) + if source.SourceIPs != nil { + schemaFirewallRuleRequest.SourceIPs = make([]string, len(source.SourceIPs)) + for i := 0; i < len(source.SourceIPs); i++ { + schemaFirewallRuleRequest.SourceIPs[i] = stringFromIPNet(source.SourceIPs[i]) + } + } + if source.DestinationIPs != nil { + schemaFirewallRuleRequest.DestinationIPs = make([]string, len(source.DestinationIPs)) + for j := 0; j < len(source.DestinationIPs); j++ { + schemaFirewallRuleRequest.DestinationIPs[j] = stringFromIPNet(source.DestinationIPs[j]) + } + } + schemaFirewallRuleRequest.Protocol = string(source.Protocol) + schemaFirewallRuleRequest.Port = source.Port + schemaFirewallRuleRequest.Description = source.Description + return schemaFirewallRuleRequest +} +func (c *converterImpl) hcloudFloatingIPProtectionToSchemaFloatingIPProtection(source FloatingIPProtection) schema.FloatingIPProtection { + var schemaFloatingIPProtection schema.FloatingIPProtection + schemaFloatingIPProtection.Delete = source.Delete + return schemaFloatingIPProtection +} +func (c *converterImpl) hcloudImageProtectionToSchemaImageProtection(source ImageProtection) schema.ImageProtection { + var schemaImageProtection schema.ImageProtection + schemaImageProtection.Delete = source.Delete + return schemaImageProtection +} +func (c *converterImpl) hcloudLoadBalancerAlgorithmToSchemaLoadBalancerAlgorithm(source LoadBalancerAlgorithm) schema.LoadBalancerAlgorithm { + var schemaLoadBalancerAlgorithm schema.LoadBalancerAlgorithm + schemaLoadBalancerAlgorithm.Type = string(source.Type) + return schemaLoadBalancerAlgorithm +} +func (c *converterImpl) hcloudLoadBalancerCreateOptsServiceToSchemaLoadBalancerCreateRequestService(source LoadBalancerCreateOptsService) schema.LoadBalancerCreateRequestService { + var schemaLoadBalancerCreateRequestService schema.LoadBalancerCreateRequestService + schemaLoadBalancerCreateRequestService.Protocol = string(source.Protocol) + schemaLoadBalancerCreateRequestService.ListenPort = source.ListenPort + schemaLoadBalancerCreateRequestService.DestinationPort = source.DestinationPort + schemaLoadBalancerCreateRequestService.Proxyprotocol = source.Proxyprotocol + schemaLoadBalancerCreateRequestService.HTTP = c.pHcloudLoadBalancerCreateOptsServiceHTTPToPSchemaLoadBalancerCreateRequestServiceHTTP(source.HTTP) + schemaLoadBalancerCreateRequestService.HealthCheck = c.pHcloudLoadBalancerCreateOptsServiceHealthCheckToPSchemaLoadBalancerCreateRequestServiceHealthCheck(source.HealthCheck) + return schemaLoadBalancerCreateRequestService +} +func (c *converterImpl) hcloudLoadBalancerCreateOptsTargetToSchemaLoadBalancerCreateRequestTarget(source LoadBalancerCreateOptsTarget) schema.LoadBalancerCreateRequestTarget { + var schemaLoadBalancerCreateRequestTarget schema.LoadBalancerCreateRequestTarget + schemaLoadBalancerCreateRequestTarget.Type = string(source.Type) + schemaLoadBalancerCreateRequestTarget.Server = schemaFromLoadBalancerCreateOptsTargetServer(source.Server) + schemaLoadBalancerCreateRequestTarget.LabelSelector = schemaFromLoadBalancerCreateOptsTargetLabelSelector(source.LabelSelector) + schemaLoadBalancerCreateRequestTarget.IP = schemaFromLoadBalancerCreateOptsTargetIP(source.IP) + schemaLoadBalancerCreateRequestTarget.UsePrivateIP = source.UsePrivateIP + return schemaLoadBalancerCreateRequestTarget +} +func (c *converterImpl) hcloudLoadBalancerPrivateNetToSchemaLoadBalancerPrivateNet(source LoadBalancerPrivateNet) schema.LoadBalancerPrivateNet { + var schemaLoadBalancerPrivateNet schema.LoadBalancerPrivateNet + schemaLoadBalancerPrivateNet.Network = c.pHcloudNetworkToInt64(source.Network) + schemaLoadBalancerPrivateNet.IP = stringFromIP(source.IP) + return schemaLoadBalancerPrivateNet +} +func (c *converterImpl) hcloudLoadBalancerProtectionToSchemaLoadBalancerProtection(source LoadBalancerProtection) schema.LoadBalancerProtection { + var schemaLoadBalancerProtection schema.LoadBalancerProtection + schemaLoadBalancerProtection.Delete = source.Delete + return schemaLoadBalancerProtection +} +func (c *converterImpl) hcloudLoadBalancerPublicNetIPv4ToSchemaLoadBalancerPublicNetIPv4(source LoadBalancerPublicNetIPv4) schema.LoadBalancerPublicNetIPv4 { + var schemaLoadBalancerPublicNetIPv4 schema.LoadBalancerPublicNetIPv4 + schemaLoadBalancerPublicNetIPv4.IP = stringFromIP(source.IP) + schemaLoadBalancerPublicNetIPv4.DNSPtr = source.DNSPtr + return schemaLoadBalancerPublicNetIPv4 +} +func (c *converterImpl) hcloudLoadBalancerPublicNetIPv6ToSchemaLoadBalancerPublicNetIPv6(source LoadBalancerPublicNetIPv6) schema.LoadBalancerPublicNetIPv6 { + var schemaLoadBalancerPublicNetIPv6 schema.LoadBalancerPublicNetIPv6 + schemaLoadBalancerPublicNetIPv6.IP = stringFromIP(source.IP) + schemaLoadBalancerPublicNetIPv6.DNSPtr = source.DNSPtr + return schemaLoadBalancerPublicNetIPv6 +} +func (c *converterImpl) hcloudLoadBalancerPublicNetToSchemaLoadBalancerPublicNet(source LoadBalancerPublicNet) schema.LoadBalancerPublicNet { + var schemaLoadBalancerPublicNet schema.LoadBalancerPublicNet + schemaLoadBalancerPublicNet.Enabled = source.Enabled + schemaLoadBalancerPublicNet.IPv4 = c.hcloudLoadBalancerPublicNetIPv4ToSchemaLoadBalancerPublicNetIPv4(source.IPv4) + schemaLoadBalancerPublicNet.IPv6 = c.hcloudLoadBalancerPublicNetIPv6ToSchemaLoadBalancerPublicNetIPv6(source.IPv6) + return schemaLoadBalancerPublicNet +} +func (c *converterImpl) hcloudLoadBalancerServiceHTTPToPSchemaLoadBalancerServiceHTTP(source LoadBalancerServiceHTTP) *schema.LoadBalancerServiceHTTP { + var schemaLoadBalancerServiceHTTP schema.LoadBalancerServiceHTTP + schemaLoadBalancerServiceHTTP.CookieName = source.CookieName + schemaLoadBalancerServiceHTTP.CookieLifetime = intSecondsFromDuration(source.CookieLifetime) + if source.Certificates != nil { + schemaLoadBalancerServiceHTTP.Certificates = make([]int64, len(source.Certificates)) + for i := 0; i < len(source.Certificates); i++ { + schemaLoadBalancerServiceHTTP.Certificates[i] = int64FromCertificate(source.Certificates[i]) + } + } + schemaLoadBalancerServiceHTTP.RedirectHTTP = source.RedirectHTTP + schemaLoadBalancerServiceHTTP.StickySessions = source.StickySessions + return &schemaLoadBalancerServiceHTTP +} +func (c *converterImpl) hcloudNetworkProtectionToSchemaNetworkProtection(source NetworkProtection) schema.NetworkProtection { + var schemaNetworkProtection schema.NetworkProtection + schemaNetworkProtection.Delete = source.Delete + return schemaNetworkProtection +} +func (c *converterImpl) hcloudPriceToSchemaPrice(source Price) schema.Price { + var schemaPrice schema.Price + schemaPrice.Net = source.Net + schemaPrice.Gross = source.Gross + return schemaPrice +} +func (c *converterImpl) hcloudPrimaryIPPriceToSchemaPrice(source PrimaryIPPrice) schema.Price { + var schemaPrice schema.Price + schemaPrice.Net = source.Net + schemaPrice.Gross = source.Gross + return schemaPrice +} +func (c *converterImpl) hcloudPrimaryIPProtectionToSchemaPrimaryIPProtection(source PrimaryIPProtection) schema.PrimaryIPProtection { + var schemaPrimaryIPProtection schema.PrimaryIPProtection + schemaPrimaryIPProtection.Delete = source.Delete + return schemaPrimaryIPProtection +} +func (c *converterImpl) hcloudServerBackupPricingToSchemaPricingServerBackup(source ServerBackupPricing) schema.PricingServerBackup { + var schemaPricingServerBackup schema.PricingServerBackup + schemaPricingServerBackup.Percentage = source.Percentage + return schemaPricingServerBackup +} +func (c *converterImpl) hcloudServerProtectionToSchemaServerProtection(source ServerProtection) schema.ServerProtection { + var schemaServerProtection schema.ServerProtection + schemaServerProtection.Delete = source.Delete + schemaServerProtection.Rebuild = source.Rebuild + return schemaServerProtection +} +func (c *converterImpl) hcloudVolumeProtectionToSchemaVolumeProtection(source VolumeProtection) schema.VolumeProtection { + var schemaVolumeProtection schema.VolumeProtection + schemaVolumeProtection.Delete = source.Delete + return schemaVolumeProtection +} +func (c *converterImpl) intISOFromSchema(source schema.ISO) ISO { + var hcloudISO ISO + hcloudISO.ID = source.ID + hcloudISO.Name = source.Name + hcloudISO.Description = source.Description + hcloudISO.Type = ISOType(source.Type) + if source.Architecture != nil { + hcloudArchitecture := Architecture(*source.Architecture) + hcloudISO.Architecture = &hcloudArchitecture + } + var pTimeTime *time.Time + if source.DeprecatableResource.Deprecation != nil { + pTimeTime = &source.DeprecatableResource.Deprecation.UnavailableAfter + } + hcloudISO.Deprecated = c.pTimeTimeToTimeTime(pTimeTime) + hcloudISO.DeprecatableResource = c.schemaDeprecatableResourceToHcloudDeprecatableResource(source.DeprecatableResource) + return hcloudISO +} +func (c *converterImpl) intSchemaFromImage(source Image) schema.Image { + var schemaImage schema.Image + schemaImage.ID = source.ID + schemaImage.Status = string(source.Status) + schemaImage.Type = string(source.Type) + pString := source.Name + schemaImage.Name = &pString + schemaImage.Description = source.Description + schemaImage.ImageSize = mapZeroFloat32ToNil(source.ImageSize) + schemaImage.DiskSize = source.DiskSize + schemaImage.Created = timeToTimePtr(source.Created) + schemaImage.CreatedFrom = c.pHcloudServerToPSchemaImageCreatedFrom(source.CreatedFrom) + schemaImage.BoundTo = c.pHcloudServerToPInt64(source.BoundTo) + schemaImage.OSFlavor = source.OSFlavor + pString2 := source.OSVersion + schemaImage.OSVersion = &pString2 + schemaImage.Architecture = string(source.Architecture) + schemaImage.RapidDeploy = source.RapidDeploy + schemaImage.Protection = c.hcloudImageProtectionToSchemaImageProtection(source.Protection) + schemaImage.Deprecated = timeToTimePtr(source.Deprecated) + schemaImage.Deleted = timeToTimePtr(source.Deleted) + schemaImage.Labels = source.Labels + return schemaImage +} +func (c *converterImpl) pHcloudActionResourceToSchemaActionResourceReference(source *ActionResource) schema.ActionResourceReference { + var schemaActionResourceReference schema.ActionResourceReference + if source != nil { + var schemaActionResourceReference2 schema.ActionResourceReference + schemaActionResourceReference2.ID = (*source).ID + schemaActionResourceReference2.Type = string((*source).Type) + schemaActionResourceReference = schemaActionResourceReference2 + } + return schemaActionResourceReference +} +func (c *converterImpl) pHcloudCertificateStatusToPSchemaCertificateStatusRef(source *CertificateStatus) *schema.CertificateStatusRef { + var pSchemaCertificateStatusRef *schema.CertificateStatusRef + if source != nil { + var schemaCertificateStatusRef schema.CertificateStatusRef + schemaCertificateStatusRef.Issuance = c.hcloudCertificateStatusTypeToString((*source).Issuance) + schemaCertificateStatusRef.Renewal = c.hcloudCertificateStatusTypeToString((*source).Renewal) + schemaCertificateStatusRef.Error = c.pHcloudErrorToPSchemaError((*source).Error) + pSchemaCertificateStatusRef = &schemaCertificateStatusRef + } + return pSchemaCertificateStatusRef +} +func (c *converterImpl) pHcloudErrorToPSchemaError(source *Error) *schema.Error { + var pSchemaError *schema.Error + if source != nil { + schemaError := c.SchemaFromError((*source)) + pSchemaError = &schemaError + } + return pSchemaError +} +func (c *converterImpl) pHcloudFirewallResourceLabelSelectorToPSchemaFirewallResourceLabelSelector(source *FirewallResourceLabelSelector) *schema.FirewallResourceLabelSelector { + var pSchemaFirewallResourceLabelSelector *schema.FirewallResourceLabelSelector + if source != nil { + var schemaFirewallResourceLabelSelector schema.FirewallResourceLabelSelector + schemaFirewallResourceLabelSelector.Selector = (*source).Selector + pSchemaFirewallResourceLabelSelector = &schemaFirewallResourceLabelSelector + } + return pSchemaFirewallResourceLabelSelector +} +func (c *converterImpl) pHcloudFirewallResourceServerToPSchemaFirewallResourceServer(source *FirewallResourceServer) *schema.FirewallResourceServer { + var pSchemaFirewallResourceServer *schema.FirewallResourceServer + if source != nil { + var schemaFirewallResourceServer schema.FirewallResourceServer + schemaFirewallResourceServer.ID = (*source).ID + pSchemaFirewallResourceServer = &schemaFirewallResourceServer + } + return pSchemaFirewallResourceServer +} +func (c *converterImpl) pHcloudISOToPSchemaISO(source *ISO) *schema.ISO { + var pSchemaISO *schema.ISO + if source != nil { + var schemaISO schema.ISO + schemaISO.ID = (*source).ID + schemaISO.Name = (*source).Name + schemaISO.Description = (*source).Description + schemaISO.Type = string((*source).Type) + if (*source).Architecture != nil { + xstring := string(*(*source).Architecture) + schemaISO.Architecture = &xstring + } + schemaISO.DeprecatableResource = c.hcloudDeprecatableResourceToSchemaDeprecatableResource((*source).DeprecatableResource) + pSchemaISO = &schemaISO + } + return pSchemaISO +} +func (c *converterImpl) pHcloudImageToPSchemaImage(source *Image) *schema.Image { + var pSchemaImage *schema.Image + if source != nil { + schemaImage := c.intSchemaFromImage((*source)) + pSchemaImage = &schemaImage + } + return pSchemaImage +} +func (c *converterImpl) pHcloudLoadBalancerAddServiceOptsHTTPToPSchemaLoadBalancerActionAddServiceRequestHTTP(source *LoadBalancerAddServiceOptsHTTP) *schema.LoadBalancerActionAddServiceRequestHTTP { + var pSchemaLoadBalancerActionAddServiceRequestHTTP *schema.LoadBalancerActionAddServiceRequestHTTP + if source != nil { + var schemaLoadBalancerActionAddServiceRequestHTTP schema.LoadBalancerActionAddServiceRequestHTTP + schemaLoadBalancerActionAddServiceRequestHTTP.CookieName = (*source).CookieName + if (*source).CookieLifetime != nil { + xint := intSecondsFromDuration(*(*source).CookieLifetime) + schemaLoadBalancerActionAddServiceRequestHTTP.CookieLifetime = &xint + } + schemaLoadBalancerActionAddServiceRequestHTTP.Certificates = int64SlicePtrFromCertificatePtrSlice((*source).Certificates) + schemaLoadBalancerActionAddServiceRequestHTTP.RedirectHTTP = (*source).RedirectHTTP + schemaLoadBalancerActionAddServiceRequestHTTP.StickySessions = (*source).StickySessions + pSchemaLoadBalancerActionAddServiceRequestHTTP = &schemaLoadBalancerActionAddServiceRequestHTTP + } + return pSchemaLoadBalancerActionAddServiceRequestHTTP +} +func (c *converterImpl) pHcloudLoadBalancerAddServiceOptsHealthCheckHTTPToPSchemaLoadBalancerActionAddServiceRequestHealthCheckHTTP(source *LoadBalancerAddServiceOptsHealthCheckHTTP) *schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP { + var pSchemaLoadBalancerActionAddServiceRequestHealthCheckHTTP *schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP + if source != nil { + var schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP + schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP.Domain = (*source).Domain + schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP.Path = (*source).Path + schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP.Response = (*source).Response + schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP.StatusCodes = stringSlicePtrFromStringSlice((*source).StatusCodes) + schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP.TLS = (*source).TLS + pSchemaLoadBalancerActionAddServiceRequestHealthCheckHTTP = &schemaLoadBalancerActionAddServiceRequestHealthCheckHTTP + } + return pSchemaLoadBalancerActionAddServiceRequestHealthCheckHTTP +} +func (c *converterImpl) pHcloudLoadBalancerAddServiceOptsHealthCheckToPSchemaLoadBalancerActionAddServiceRequestHealthCheck(source *LoadBalancerAddServiceOptsHealthCheck) *schema.LoadBalancerActionAddServiceRequestHealthCheck { + var pSchemaLoadBalancerActionAddServiceRequestHealthCheck *schema.LoadBalancerActionAddServiceRequestHealthCheck + if source != nil { + var schemaLoadBalancerActionAddServiceRequestHealthCheck schema.LoadBalancerActionAddServiceRequestHealthCheck + schemaLoadBalancerActionAddServiceRequestHealthCheck.Protocol = string((*source).Protocol) + schemaLoadBalancerActionAddServiceRequestHealthCheck.Port = (*source).Port + if (*source).Interval != nil { + xint := intSecondsFromDuration(*(*source).Interval) + schemaLoadBalancerActionAddServiceRequestHealthCheck.Interval = &xint + } + if (*source).Timeout != nil { + xint2 := intSecondsFromDuration(*(*source).Timeout) + schemaLoadBalancerActionAddServiceRequestHealthCheck.Timeout = &xint2 + } + schemaLoadBalancerActionAddServiceRequestHealthCheck.Retries = (*source).Retries + schemaLoadBalancerActionAddServiceRequestHealthCheck.HTTP = c.pHcloudLoadBalancerAddServiceOptsHealthCheckHTTPToPSchemaLoadBalancerActionAddServiceRequestHealthCheckHTTP((*source).HTTP) + pSchemaLoadBalancerActionAddServiceRequestHealthCheck = &schemaLoadBalancerActionAddServiceRequestHealthCheck + } + return pSchemaLoadBalancerActionAddServiceRequestHealthCheck +} +func (c *converterImpl) pHcloudLoadBalancerAlgorithmToPSchemaLoadBalancerCreateRequestAlgorithm(source *LoadBalancerAlgorithm) *schema.LoadBalancerCreateRequestAlgorithm { + var pSchemaLoadBalancerCreateRequestAlgorithm *schema.LoadBalancerCreateRequestAlgorithm + if source != nil { + var schemaLoadBalancerCreateRequestAlgorithm schema.LoadBalancerCreateRequestAlgorithm + schemaLoadBalancerCreateRequestAlgorithm.Type = string((*source).Type) + pSchemaLoadBalancerCreateRequestAlgorithm = &schemaLoadBalancerCreateRequestAlgorithm + } + return pSchemaLoadBalancerCreateRequestAlgorithm +} +func (c *converterImpl) pHcloudLoadBalancerCreateOptsServiceHTTPToPSchemaLoadBalancerCreateRequestServiceHTTP(source *LoadBalancerCreateOptsServiceHTTP) *schema.LoadBalancerCreateRequestServiceHTTP { + var pSchemaLoadBalancerCreateRequestServiceHTTP *schema.LoadBalancerCreateRequestServiceHTTP + if source != nil { + var schemaLoadBalancerCreateRequestServiceHTTP schema.LoadBalancerCreateRequestServiceHTTP + schemaLoadBalancerCreateRequestServiceHTTP.CookieName = (*source).CookieName + if (*source).CookieLifetime != nil { + xint := intSecondsFromDuration(*(*source).CookieLifetime) + schemaLoadBalancerCreateRequestServiceHTTP.CookieLifetime = &xint + } + schemaLoadBalancerCreateRequestServiceHTTP.Certificates = int64SlicePtrFromCertificatePtrSlice((*source).Certificates) + schemaLoadBalancerCreateRequestServiceHTTP.RedirectHTTP = (*source).RedirectHTTP + schemaLoadBalancerCreateRequestServiceHTTP.StickySessions = (*source).StickySessions + pSchemaLoadBalancerCreateRequestServiceHTTP = &schemaLoadBalancerCreateRequestServiceHTTP + } + return pSchemaLoadBalancerCreateRequestServiceHTTP +} +func (c *converterImpl) pHcloudLoadBalancerCreateOptsServiceHealthCheckHTTPToPSchemaLoadBalancerCreateRequestServiceHealthCheckHTTP(source *LoadBalancerCreateOptsServiceHealthCheckHTTP) *schema.LoadBalancerCreateRequestServiceHealthCheckHTTP { + var pSchemaLoadBalancerCreateRequestServiceHealthCheckHTTP *schema.LoadBalancerCreateRequestServiceHealthCheckHTTP + if source != nil { + var schemaLoadBalancerCreateRequestServiceHealthCheckHTTP schema.LoadBalancerCreateRequestServiceHealthCheckHTTP + schemaLoadBalancerCreateRequestServiceHealthCheckHTTP.Domain = (*source).Domain + schemaLoadBalancerCreateRequestServiceHealthCheckHTTP.Path = (*source).Path + schemaLoadBalancerCreateRequestServiceHealthCheckHTTP.Response = (*source).Response + schemaLoadBalancerCreateRequestServiceHealthCheckHTTP.StatusCodes = stringSlicePtrFromStringSlice((*source).StatusCodes) + schemaLoadBalancerCreateRequestServiceHealthCheckHTTP.TLS = (*source).TLS + pSchemaLoadBalancerCreateRequestServiceHealthCheckHTTP = &schemaLoadBalancerCreateRequestServiceHealthCheckHTTP + } + return pSchemaLoadBalancerCreateRequestServiceHealthCheckHTTP +} +func (c *converterImpl) pHcloudLoadBalancerCreateOptsServiceHealthCheckToPSchemaLoadBalancerCreateRequestServiceHealthCheck(source *LoadBalancerCreateOptsServiceHealthCheck) *schema.LoadBalancerCreateRequestServiceHealthCheck { + var pSchemaLoadBalancerCreateRequestServiceHealthCheck *schema.LoadBalancerCreateRequestServiceHealthCheck + if source != nil { + var schemaLoadBalancerCreateRequestServiceHealthCheck schema.LoadBalancerCreateRequestServiceHealthCheck + schemaLoadBalancerCreateRequestServiceHealthCheck.Protocol = string((*source).Protocol) + schemaLoadBalancerCreateRequestServiceHealthCheck.Port = (*source).Port + if (*source).Interval != nil { + xint := intSecondsFromDuration(*(*source).Interval) + schemaLoadBalancerCreateRequestServiceHealthCheck.Interval = &xint + } + if (*source).Timeout != nil { + xint2 := intSecondsFromDuration(*(*source).Timeout) + schemaLoadBalancerCreateRequestServiceHealthCheck.Timeout = &xint2 + } + schemaLoadBalancerCreateRequestServiceHealthCheck.Retries = (*source).Retries + schemaLoadBalancerCreateRequestServiceHealthCheck.HTTP = c.pHcloudLoadBalancerCreateOptsServiceHealthCheckHTTPToPSchemaLoadBalancerCreateRequestServiceHealthCheckHTTP((*source).HTTP) + pSchemaLoadBalancerCreateRequestServiceHealthCheck = &schemaLoadBalancerCreateRequestServiceHealthCheck + } + return pSchemaLoadBalancerCreateRequestServiceHealthCheck +} +func (c *converterImpl) pHcloudLoadBalancerServiceHealthCheckHTTPToPSchemaLoadBalancerServiceHealthCheckHTTP(source *LoadBalancerServiceHealthCheckHTTP) *schema.LoadBalancerServiceHealthCheckHTTP { + var pSchemaLoadBalancerServiceHealthCheckHTTP *schema.LoadBalancerServiceHealthCheckHTTP + if source != nil { + var schemaLoadBalancerServiceHealthCheckHTTP schema.LoadBalancerServiceHealthCheckHTTP + schemaLoadBalancerServiceHealthCheckHTTP.Domain = (*source).Domain + schemaLoadBalancerServiceHealthCheckHTTP.Path = (*source).Path + schemaLoadBalancerServiceHealthCheckHTTP.Response = (*source).Response + schemaLoadBalancerServiceHealthCheckHTTP.StatusCodes = (*source).StatusCodes + schemaLoadBalancerServiceHealthCheckHTTP.TLS = (*source).TLS + pSchemaLoadBalancerServiceHealthCheckHTTP = &schemaLoadBalancerServiceHealthCheckHTTP + } + return pSchemaLoadBalancerServiceHealthCheckHTTP +} +func (c *converterImpl) pHcloudLoadBalancerTargetIPToPSchemaLoadBalancerTargetIP(source *LoadBalancerTargetIP) *schema.LoadBalancerTargetIP { + var pSchemaLoadBalancerTargetIP *schema.LoadBalancerTargetIP + if source != nil { + var schemaLoadBalancerTargetIP schema.LoadBalancerTargetIP + schemaLoadBalancerTargetIP.IP = (*source).IP + pSchemaLoadBalancerTargetIP = &schemaLoadBalancerTargetIP + } + return pSchemaLoadBalancerTargetIP +} +func (c *converterImpl) pHcloudLoadBalancerTargetLabelSelectorToPSchemaLoadBalancerTargetLabelSelector(source *LoadBalancerTargetLabelSelector) *schema.LoadBalancerTargetLabelSelector { + var pSchemaLoadBalancerTargetLabelSelector *schema.LoadBalancerTargetLabelSelector + if source != nil { + var schemaLoadBalancerTargetLabelSelector schema.LoadBalancerTargetLabelSelector + schemaLoadBalancerTargetLabelSelector.Selector = (*source).Selector + pSchemaLoadBalancerTargetLabelSelector = &schemaLoadBalancerTargetLabelSelector + } + return pSchemaLoadBalancerTargetLabelSelector +} +func (c *converterImpl) pHcloudLoadBalancerTargetServerToPSchemaLoadBalancerTargetServer(source *LoadBalancerTargetServer) *schema.LoadBalancerTargetServer { + var pSchemaLoadBalancerTargetServer *schema.LoadBalancerTargetServer + if source != nil { + schemaLoadBalancerTargetServer := c.SchemaFromLoadBalancerServerTarget((*source)) + pSchemaLoadBalancerTargetServer = &schemaLoadBalancerTargetServer + } + return pSchemaLoadBalancerTargetServer +} +func (c *converterImpl) pHcloudLoadBalancerToInt64(source *LoadBalancer) int64 { + var xint64 int64 + if source != nil { + xint64 = int64FromLoadBalancer((*source)) + } + return xint64 +} +func (c *converterImpl) pHcloudLoadBalancerTypeToSchemaIDOrName(source *LoadBalancerType) schema.IDOrName { + var schemaIDOrName schema.IDOrName + if source != nil { + var schemaIDOrName2 schema.IDOrName + schemaIDOrName2.ID = (*source).ID + schemaIDOrName2.Name = (*source).Name + schemaIDOrName = schemaIDOrName2 + } + return schemaIDOrName +} +func (c *converterImpl) pHcloudLoadBalancerUpdateServiceOptsHTTPToPSchemaLoadBalancerActionUpdateServiceRequestHTTP(source *LoadBalancerUpdateServiceOptsHTTP) *schema.LoadBalancerActionUpdateServiceRequestHTTP { + var pSchemaLoadBalancerActionUpdateServiceRequestHTTP *schema.LoadBalancerActionUpdateServiceRequestHTTP + if source != nil { + var schemaLoadBalancerActionUpdateServiceRequestHTTP schema.LoadBalancerActionUpdateServiceRequestHTTP + schemaLoadBalancerActionUpdateServiceRequestHTTP.CookieName = (*source).CookieName + if (*source).CookieLifetime != nil { + xint := intSecondsFromDuration(*(*source).CookieLifetime) + schemaLoadBalancerActionUpdateServiceRequestHTTP.CookieLifetime = &xint + } + schemaLoadBalancerActionUpdateServiceRequestHTTP.Certificates = int64SlicePtrFromCertificatePtrSlice((*source).Certificates) + schemaLoadBalancerActionUpdateServiceRequestHTTP.RedirectHTTP = (*source).RedirectHTTP + schemaLoadBalancerActionUpdateServiceRequestHTTP.StickySessions = (*source).StickySessions + pSchemaLoadBalancerActionUpdateServiceRequestHTTP = &schemaLoadBalancerActionUpdateServiceRequestHTTP + } + return pSchemaLoadBalancerActionUpdateServiceRequestHTTP +} +func (c *converterImpl) pHcloudLoadBalancerUpdateServiceOptsHealthCheckHTTPToPSchemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP(source *LoadBalancerUpdateServiceOptsHealthCheckHTTP) *schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP { + var pSchemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP *schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP + if source != nil { + var schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP + schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP.Domain = (*source).Domain + schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP.Path = (*source).Path + schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP.Response = (*source).Response + schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP.StatusCodes = stringSlicePtrFromStringSlice((*source).StatusCodes) + schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP.TLS = (*source).TLS + pSchemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP = &schemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP + } + return pSchemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP +} +func (c *converterImpl) pHcloudLoadBalancerUpdateServiceOptsHealthCheckToPSchemaLoadBalancerActionUpdateServiceRequestHealthCheck(source *LoadBalancerUpdateServiceOptsHealthCheck) *schema.LoadBalancerActionUpdateServiceRequestHealthCheck { + var pSchemaLoadBalancerActionUpdateServiceRequestHealthCheck *schema.LoadBalancerActionUpdateServiceRequestHealthCheck + if source != nil { + var schemaLoadBalancerActionUpdateServiceRequestHealthCheck schema.LoadBalancerActionUpdateServiceRequestHealthCheck + schemaLoadBalancerActionUpdateServiceRequestHealthCheck.Protocol = stringPtrFromLoadBalancerServiceProtocol((*source).Protocol) + schemaLoadBalancerActionUpdateServiceRequestHealthCheck.Port = (*source).Port + if (*source).Interval != nil { + xint := intSecondsFromDuration(*(*source).Interval) + schemaLoadBalancerActionUpdateServiceRequestHealthCheck.Interval = &xint + } + if (*source).Timeout != nil { + xint2 := intSecondsFromDuration(*(*source).Timeout) + schemaLoadBalancerActionUpdateServiceRequestHealthCheck.Timeout = &xint2 + } + schemaLoadBalancerActionUpdateServiceRequestHealthCheck.Retries = (*source).Retries + schemaLoadBalancerActionUpdateServiceRequestHealthCheck.HTTP = c.pHcloudLoadBalancerUpdateServiceOptsHealthCheckHTTPToPSchemaLoadBalancerActionUpdateServiceRequestHealthCheckHTTP((*source).HTTP) + pSchemaLoadBalancerActionUpdateServiceRequestHealthCheck = &schemaLoadBalancerActionUpdateServiceRequestHealthCheck + } + return pSchemaLoadBalancerActionUpdateServiceRequestHealthCheck +} +func (c *converterImpl) pHcloudLocationToPString(source *Location) *string { + var pString *string + if source != nil { + xstring := stringFromLocation((*source)) + pString = &xstring + } + return pString +} +func (c *converterImpl) pHcloudLocationToString(source *Location) string { + var xstring string + if source != nil { + xstring = stringFromLocation((*source)) + } + return xstring +} +func (c *converterImpl) pHcloudNetworkToInt64(source *Network) int64 { + var xint64 int64 + if source != nil { + xint64 = int64FromNetwork((*source)) + } + return xint64 +} +func (c *converterImpl) pHcloudNetworkToPInt64(source *Network) *int64 { + var pInt64 *int64 + if source != nil { + xint64 := int64FromNetwork((*source)) + pInt64 = &xint64 + } + return pInt64 +} +func (c *converterImpl) pHcloudPlacementGroupToPSchemaPlacementGroup(source *PlacementGroup) *schema.PlacementGroup { + var pSchemaPlacementGroup *schema.PlacementGroup + if source != nil { + var schemaPlacementGroup schema.PlacementGroup + schemaPlacementGroup.ID = (*source).ID + schemaPlacementGroup.Name = (*source).Name + schemaPlacementGroup.Labels = (*source).Labels + schemaPlacementGroup.Created = c.timeTimeToTimeTime((*source).Created) + schemaPlacementGroup.Servers = (*source).Servers + schemaPlacementGroup.Type = string((*source).Type) + pSchemaPlacementGroup = &schemaPlacementGroup + } + return pSchemaPlacementGroup +} +func (c *converterImpl) pHcloudServerToInt64(source *Server) int64 { + var xint64 int64 + if source != nil { + xint64 = int64FromServer((*source)) + } + return xint64 +} +func (c *converterImpl) pHcloudServerToPInt64(source *Server) *int64 { + var pInt64 *int64 + if source != nil { + xint64 := int64FromServer((*source)) + pInt64 = &xint64 + } + return pInt64 +} +func (c *converterImpl) pHcloudServerToPSchemaImageCreatedFrom(source *Server) *schema.ImageCreatedFrom { + var pSchemaImageCreatedFrom *schema.ImageCreatedFrom + if source != nil { + var schemaImageCreatedFrom schema.ImageCreatedFrom + schemaImageCreatedFrom.ID = (*source).ID + schemaImageCreatedFrom.Name = (*source).Name + pSchemaImageCreatedFrom = &schemaImageCreatedFrom + } + return pSchemaImageCreatedFrom +} +func (c *converterImpl) pNetIPNetToString(source *net.IPNet) string { + var xstring string + if source != nil { + xstring = stringFromIPNet((*source)) + } + return xstring +} +func (c *converterImpl) pSchemaCertificateStatusRefToPHcloudCertificateStatus(source *schema.CertificateStatusRef) *CertificateStatus { + var pHcloudCertificateStatus *CertificateStatus + if source != nil { + var hcloudCertificateStatus CertificateStatus + hcloudCertificateStatus.Issuance = CertificateStatusType((*source).Issuance) + hcloudCertificateStatus.Renewal = CertificateStatusType((*source).Renewal) + hcloudCertificateStatus.Error = c.pSchemaErrorToPHcloudError((*source).Error) + pHcloudCertificateStatus = &hcloudCertificateStatus + } + return pHcloudCertificateStatus +} +func (c *converterImpl) pSchemaErrorToPHcloudError(source *schema.Error) *Error { + var pHcloudError *Error + if source != nil { + hcloudError := c.ErrorFromSchema((*source)) + pHcloudError = &hcloudError + } + return pHcloudError +} +func (c *converterImpl) pSchemaFirewallResourceLabelSelectorToPHcloudFirewallResourceLabelSelector(source *schema.FirewallResourceLabelSelector) *FirewallResourceLabelSelector { + var pHcloudFirewallResourceLabelSelector *FirewallResourceLabelSelector + if source != nil { + var hcloudFirewallResourceLabelSelector FirewallResourceLabelSelector + hcloudFirewallResourceLabelSelector.Selector = (*source).Selector + pHcloudFirewallResourceLabelSelector = &hcloudFirewallResourceLabelSelector + } + return pHcloudFirewallResourceLabelSelector +} +func (c *converterImpl) pSchemaFirewallResourceServerToPHcloudFirewallResourceServer(source *schema.FirewallResourceServer) *FirewallResourceServer { + var pHcloudFirewallResourceServer *FirewallResourceServer + if source != nil { + var hcloudFirewallResourceServer FirewallResourceServer + hcloudFirewallResourceServer.ID = (*source).ID + pHcloudFirewallResourceServer = &hcloudFirewallResourceServer + } + return pHcloudFirewallResourceServer +} +func (c *converterImpl) pSchemaISOToPHcloudISO(source *schema.ISO) *ISO { + var pHcloudISO *ISO + if source != nil { + hcloudISO := c.intISOFromSchema((*source)) + pHcloudISO = &hcloudISO + } + return pHcloudISO +} +func (c *converterImpl) pSchemaImageCreatedFromToPHcloudServer(source *schema.ImageCreatedFrom) *Server { + var pHcloudServer *Server + if source != nil { + hcloudServer := serverFromImageCreatedFromSchema((*source)) + pHcloudServer = &hcloudServer + } + return pHcloudServer +} +func (c *converterImpl) pSchemaImageToPHcloudImage(source *schema.Image) *Image { + var pHcloudImage *Image + if source != nil { + var hcloudImage Image + hcloudImage.ID = (*source).ID + if (*source).Name != nil { + hcloudImage.Name = *(*source).Name + } + hcloudImage.Type = ImageType((*source).Type) + hcloudImage.Status = ImageStatus((*source).Status) + hcloudImage.Description = (*source).Description + if (*source).ImageSize != nil { + hcloudImage.ImageSize = *(*source).ImageSize + } + hcloudImage.DiskSize = (*source).DiskSize + hcloudImage.Created = c.pTimeTimeToTimeTime((*source).Created) + hcloudImage.CreatedFrom = c.pSchemaImageCreatedFromToPHcloudServer((*source).CreatedFrom) + if (*source).BoundTo != nil { + hcloudServer := serverFromInt64(*(*source).BoundTo) + hcloudImage.BoundTo = &hcloudServer + } + hcloudImage.RapidDeploy = (*source).RapidDeploy + hcloudImage.OSFlavor = (*source).OSFlavor + if (*source).OSVersion != nil { + hcloudImage.OSVersion = *(*source).OSVersion + } + hcloudImage.Architecture = Architecture((*source).Architecture) + hcloudImage.Protection = c.schemaImageProtectionToHcloudImageProtection((*source).Protection) + hcloudImage.Deprecated = c.pTimeTimeToTimeTime((*source).Deprecated) + hcloudImage.Labels = (*source).Labels + hcloudImage.Deleted = c.pTimeTimeToTimeTime((*source).Deleted) + pHcloudImage = &hcloudImage + } + return pHcloudImage +} +func (c *converterImpl) pSchemaLoadBalancerServiceHTTPToHcloudLoadBalancerServiceHTTP(source *schema.LoadBalancerServiceHTTP) LoadBalancerServiceHTTP { + var hcloudLoadBalancerServiceHTTP LoadBalancerServiceHTTP + if source != nil { + var hcloudLoadBalancerServiceHTTP2 LoadBalancerServiceHTTP + hcloudLoadBalancerServiceHTTP2.CookieName = (*source).CookieName + hcloudLoadBalancerServiceHTTP2.CookieLifetime = durationFromIntSeconds((*source).CookieLifetime) + if (*source).Certificates != nil { + hcloudLoadBalancerServiceHTTP2.Certificates = make([]*Certificate, len((*source).Certificates)) + for i := 0; i < len((*source).Certificates); i++ { + hcloudLoadBalancerServiceHTTP2.Certificates[i] = certificateFromInt64((*source).Certificates[i]) + } + } + hcloudLoadBalancerServiceHTTP2.RedirectHTTP = (*source).RedirectHTTP + hcloudLoadBalancerServiceHTTP2.StickySessions = (*source).StickySessions + hcloudLoadBalancerServiceHTTP = hcloudLoadBalancerServiceHTTP2 + } + return hcloudLoadBalancerServiceHTTP +} +func (c *converterImpl) pSchemaLoadBalancerServiceHealthCheckHTTPToPHcloudLoadBalancerServiceHealthCheckHTTP(source *schema.LoadBalancerServiceHealthCheckHTTP) *LoadBalancerServiceHealthCheckHTTP { + var pHcloudLoadBalancerServiceHealthCheckHTTP *LoadBalancerServiceHealthCheckHTTP + if source != nil { + var hcloudLoadBalancerServiceHealthCheckHTTP LoadBalancerServiceHealthCheckHTTP + hcloudLoadBalancerServiceHealthCheckHTTP.Domain = (*source).Domain + hcloudLoadBalancerServiceHealthCheckHTTP.Path = (*source).Path + hcloudLoadBalancerServiceHealthCheckHTTP.Response = (*source).Response + hcloudLoadBalancerServiceHealthCheckHTTP.StatusCodes = (*source).StatusCodes + hcloudLoadBalancerServiceHealthCheckHTTP.TLS = (*source).TLS + pHcloudLoadBalancerServiceHealthCheckHTTP = &hcloudLoadBalancerServiceHealthCheckHTTP + } + return pHcloudLoadBalancerServiceHealthCheckHTTP +} +func (c *converterImpl) pSchemaLoadBalancerTargetIPToPHcloudLoadBalancerTargetIP(source *schema.LoadBalancerTargetIP) *LoadBalancerTargetIP { + var pHcloudLoadBalancerTargetIP *LoadBalancerTargetIP + if source != nil { + var hcloudLoadBalancerTargetIP LoadBalancerTargetIP + hcloudLoadBalancerTargetIP.IP = (*source).IP + pHcloudLoadBalancerTargetIP = &hcloudLoadBalancerTargetIP + } + return pHcloudLoadBalancerTargetIP +} +func (c *converterImpl) pSchemaLoadBalancerTargetLabelSelectorToPHcloudLoadBalancerTargetLabelSelector(source *schema.LoadBalancerTargetLabelSelector) *LoadBalancerTargetLabelSelector { + var pHcloudLoadBalancerTargetLabelSelector *LoadBalancerTargetLabelSelector + if source != nil { + var hcloudLoadBalancerTargetLabelSelector LoadBalancerTargetLabelSelector + hcloudLoadBalancerTargetLabelSelector.Selector = (*source).Selector + pHcloudLoadBalancerTargetLabelSelector = &hcloudLoadBalancerTargetLabelSelector + } + return pHcloudLoadBalancerTargetLabelSelector +} +func (c *converterImpl) pSchemaLoadBalancerTargetServerToPHcloudLoadBalancerTargetServer(source *schema.LoadBalancerTargetServer) *LoadBalancerTargetServer { + var pHcloudLoadBalancerTargetServer *LoadBalancerTargetServer + if source != nil { + hcloudLoadBalancerTargetServer := c.LoadBalancerTargetServerFromSchema((*source)) + pHcloudLoadBalancerTargetServer = &hcloudLoadBalancerTargetServer + } + return pHcloudLoadBalancerTargetServer +} +func (c *converterImpl) pSchemaPlacementGroupToPHcloudPlacementGroup(source *schema.PlacementGroup) *PlacementGroup { + var pHcloudPlacementGroup *PlacementGroup + if source != nil { + var hcloudPlacementGroup PlacementGroup + hcloudPlacementGroup.ID = (*source).ID + hcloudPlacementGroup.Name = (*source).Name + hcloudPlacementGroup.Labels = (*source).Labels + hcloudPlacementGroup.Created = c.timeTimeToTimeTime((*source).Created) + hcloudPlacementGroup.Servers = (*source).Servers + hcloudPlacementGroup.Type = PlacementGroupType((*source).Type) + pHcloudPlacementGroup = &hcloudPlacementGroup + } + return pHcloudPlacementGroup +} +func (c *converterImpl) pTimeTimeToTimeTime(source *time.Time) time.Time { + var timeTime time.Time + if source != nil { + timeTime = (*source) + } + return timeTime +} +func (c *converterImpl) schemaActionResourceReferenceToPHcloudActionResource(source schema.ActionResourceReference) *ActionResource { + var hcloudActionResource ActionResource + hcloudActionResource.ID = source.ID + hcloudActionResource.Type = ActionResourceType(source.Type) + return &hcloudActionResource +} +func (c *converterImpl) schemaCertificateUsedByRefToHcloudCertificateUsedByRef(source schema.CertificateUsedByRef) CertificateUsedByRef { + var hcloudCertificateUsedByRef CertificateUsedByRef + hcloudCertificateUsedByRef.ID = source.ID + hcloudCertificateUsedByRef.Type = CertificateUsedByRefType(source.Type) + return hcloudCertificateUsedByRef +} +func (c *converterImpl) schemaDatacenterServerTypesToHcloudDatacenterServerTypes(source schema.DatacenterServerTypes) DatacenterServerTypes { + var hcloudDatacenterServerTypes DatacenterServerTypes + if source.Supported != nil { + hcloudDatacenterServerTypes.Supported = make([]*ServerType, len(source.Supported)) + for i := 0; i < len(source.Supported); i++ { + hcloudDatacenterServerTypes.Supported[i] = serverTypeFromInt64(source.Supported[i]) + } + } + if source.AvailableForMigration != nil { + hcloudDatacenterServerTypes.AvailableForMigration = make([]*ServerType, len(source.AvailableForMigration)) + for j := 0; j < len(source.AvailableForMigration); j++ { + hcloudDatacenterServerTypes.AvailableForMigration[j] = serverTypeFromInt64(source.AvailableForMigration[j]) + } + } + if source.Available != nil { + hcloudDatacenterServerTypes.Available = make([]*ServerType, len(source.Available)) + for k := 0; k < len(source.Available); k++ { + hcloudDatacenterServerTypes.Available[k] = serverTypeFromInt64(source.Available[k]) + } + } + return hcloudDatacenterServerTypes +} +func (c *converterImpl) schemaDeprecatableResourceToHcloudDeprecatableResource(source schema.DeprecatableResource) DeprecatableResource { + var hcloudDeprecatableResource DeprecatableResource + hcloudDeprecatableResource.Deprecation = c.DeprecationFromSchema(source.Deprecation) + return hcloudDeprecatableResource +} +func (c *converterImpl) schemaFirewallResourceToHcloudFirewallResource(source schema.FirewallResource) FirewallResource { + var hcloudFirewallResource FirewallResource + hcloudFirewallResource.Type = FirewallResourceType(source.Type) + hcloudFirewallResource.Server = c.pSchemaFirewallResourceServerToPHcloudFirewallResourceServer(source.Server) + hcloudFirewallResource.LabelSelector = c.pSchemaFirewallResourceLabelSelectorToPHcloudFirewallResourceLabelSelector(source.LabelSelector) + return hcloudFirewallResource +} +func (c *converterImpl) schemaFirewallRuleToHcloudFirewallRule(source schema.FirewallRule) FirewallRule { + var hcloudFirewallRule FirewallRule + hcloudFirewallRule.Direction = FirewallRuleDirection(source.Direction) + if source.SourceIPs != nil { + hcloudFirewallRule.SourceIPs = make([]net.IPNet, len(source.SourceIPs)) + for i := 0; i < len(source.SourceIPs); i++ { + hcloudFirewallRule.SourceIPs[i] = ipNetFromString(source.SourceIPs[i]) + } + } + if source.DestinationIPs != nil { + hcloudFirewallRule.DestinationIPs = make([]net.IPNet, len(source.DestinationIPs)) + for j := 0; j < len(source.DestinationIPs); j++ { + hcloudFirewallRule.DestinationIPs[j] = ipNetFromString(source.DestinationIPs[j]) + } + } + hcloudFirewallRule.Protocol = FirewallRuleProtocol(source.Protocol) + hcloudFirewallRule.Port = source.Port + hcloudFirewallRule.Description = source.Description + return hcloudFirewallRule +} +func (c *converterImpl) schemaFloatingIPProtectionToHcloudFloatingIPProtection(source schema.FloatingIPProtection) FloatingIPProtection { + var hcloudFloatingIPProtection FloatingIPProtection + hcloudFloatingIPProtection.Delete = source.Delete + return hcloudFloatingIPProtection +} +func (c *converterImpl) schemaFromFloatingIPPricing(source FloatingIPPricing) schema.PricingFloatingIP { + var schemaPricingFloatingIP schema.PricingFloatingIP + schemaPricingFloatingIP.PriceMonthly = c.hcloudPriceToSchemaPrice(source.Monthly) + return schemaPricingFloatingIP +} +func (c *converterImpl) schemaFromFloatingIPTypeLocationPricing(source FloatingIPTypeLocationPricing) schema.PricingFloatingIPTypePrice { + var schemaPricingFloatingIPTypePrice schema.PricingFloatingIPTypePrice + schemaPricingFloatingIPTypePrice.Location = c.pHcloudLocationToString(source.Location) + schemaPricingFloatingIPTypePrice.PriceMonthly = c.hcloudPriceToSchemaPrice(source.Monthly) + return schemaPricingFloatingIPTypePrice +} +func (c *converterImpl) schemaFromFloatingIPTypePricing(source FloatingIPTypePricing) schema.PricingFloatingIPType { + var schemaPricingFloatingIPType schema.PricingFloatingIPType + schemaPricingFloatingIPType.Type = string(source.Type) + if source.Pricings != nil { + schemaPricingFloatingIPType.Prices = make([]schema.PricingFloatingIPTypePrice, len(source.Pricings)) + for i := 0; i < len(source.Pricings); i++ { + schemaPricingFloatingIPType.Prices[i] = c.schemaFromFloatingIPTypeLocationPricing(source.Pricings[i]) + } + } + return schemaPricingFloatingIPType +} +func (c *converterImpl) schemaFromImagePricing(source ImagePricing) schema.PricingImage { + var schemaPricingImage schema.PricingImage + schemaPricingImage.PricePerGBMonth = c.hcloudPriceToSchemaPrice(source.PerGBMonth) + return schemaPricingImage +} +func (c *converterImpl) schemaFromLoadBalancerTypePricing(source LoadBalancerTypePricing) schema.PricingLoadBalancerType { + var schemaPricingLoadBalancerType schema.PricingLoadBalancerType + var pInt64 *int64 + if source.LoadBalancerType != nil { + pInt64 = &source.LoadBalancerType.ID + } + if pInt64 != nil { + schemaPricingLoadBalancerType.ID = *pInt64 + } + var pString *string + if source.LoadBalancerType != nil { + pString = &source.LoadBalancerType.Name + } + if pString != nil { + schemaPricingLoadBalancerType.Name = *pString + } + if source.Pricings != nil { + schemaPricingLoadBalancerType.Prices = make([]schema.PricingLoadBalancerTypePrice, len(source.Pricings)) + for i := 0; i < len(source.Pricings); i++ { + schemaPricingLoadBalancerType.Prices[i] = c.SchemaFromLoadBalancerTypeLocationPricing(source.Pricings[i]) + } + } + return schemaPricingLoadBalancerType +} +func (c *converterImpl) schemaFromPrimaryIPPricing(source PrimaryIPPricing) schema.PricingPrimaryIP { + var schemaPricingPrimaryIP schema.PricingPrimaryIP + schemaPricingPrimaryIP.Type = source.Type + if source.Pricings != nil { + schemaPricingPrimaryIP.Prices = make([]schema.PricingPrimaryIPTypePrice, len(source.Pricings)) + for i := 0; i < len(source.Pricings); i++ { + schemaPricingPrimaryIP.Prices[i] = c.schemaFromPrimaryIPTypePricing(source.Pricings[i]) + } + } + return schemaPricingPrimaryIP +} +func (c *converterImpl) schemaFromPrimaryIPTypePricing(source PrimaryIPTypePricing) schema.PricingPrimaryIPTypePrice { + var schemaPricingPrimaryIPTypePrice schema.PricingPrimaryIPTypePrice + schemaPricingPrimaryIPTypePrice.Datacenter = source.Datacenter + schemaPricingPrimaryIPTypePrice.Location = source.Location + schemaPricingPrimaryIPTypePrice.PriceHourly = c.hcloudPrimaryIPPriceToSchemaPrice(source.Hourly) + schemaPricingPrimaryIPTypePrice.PriceMonthly = c.hcloudPrimaryIPPriceToSchemaPrice(source.Monthly) + return schemaPricingPrimaryIPTypePrice +} +func (c *converterImpl) schemaFromServerTypeLocationPricing(source ServerTypeLocationPricing) schema.PricingServerTypePrice { + var schemaPricingServerTypePrice schema.PricingServerTypePrice + schemaPricingServerTypePrice.Location = c.pHcloudLocationToString(source.Location) + schemaPricingServerTypePrice.PriceHourly = c.hcloudPriceToSchemaPrice(source.Hourly) + schemaPricingServerTypePrice.PriceMonthly = c.hcloudPriceToSchemaPrice(source.Monthly) + schemaPricingServerTypePrice.IncludedTraffic = source.IncludedTraffic + schemaPricingServerTypePrice.PricePerTBTraffic = c.hcloudPriceToSchemaPrice(source.PerTBTraffic) + return schemaPricingServerTypePrice +} +func (c *converterImpl) schemaFromServerTypePricing(source ServerTypePricing) schema.PricingServerType { + var schemaPricingServerType schema.PricingServerType + var pInt64 *int64 + if source.ServerType != nil { + pInt64 = &source.ServerType.ID + } + if pInt64 != nil { + schemaPricingServerType.ID = *pInt64 + } + var pString *string + if source.ServerType != nil { + pString = &source.ServerType.Name + } + if pString != nil { + schemaPricingServerType.Name = *pString + } + if source.Pricings != nil { + schemaPricingServerType.Prices = make([]schema.PricingServerTypePrice, len(source.Pricings)) + for i := 0; i < len(source.Pricings); i++ { + schemaPricingServerType.Prices[i] = c.schemaFromServerTypeLocationPricing(source.Pricings[i]) + } + } + return schemaPricingServerType +} +func (c *converterImpl) schemaFromTrafficPricing(source TrafficPricing) schema.PricingTraffic { + var schemaPricingTraffic schema.PricingTraffic + schemaPricingTraffic.PricePerTB = c.hcloudPriceToSchemaPrice(source.PerTB) + return schemaPricingTraffic +} +func (c *converterImpl) schemaFromVolumePricing(source VolumePricing) schema.PricingVolume { + var schemaPricingVolume schema.PricingVolume + schemaPricingVolume.PricePerGBPerMonth = c.hcloudPriceToSchemaPrice(source.PerGBMonthly) + return schemaPricingVolume +} +func (c *converterImpl) schemaImageProtectionToHcloudImageProtection(source schema.ImageProtection) ImageProtection { + var hcloudImageProtection ImageProtection + hcloudImageProtection.Delete = source.Delete + return hcloudImageProtection +} +func (c *converterImpl) schemaLoadBalancerAlgorithmToHcloudLoadBalancerAlgorithm(source schema.LoadBalancerAlgorithm) LoadBalancerAlgorithm { + var hcloudLoadBalancerAlgorithm LoadBalancerAlgorithm + hcloudLoadBalancerAlgorithm.Type = LoadBalancerAlgorithmType(source.Type) + return hcloudLoadBalancerAlgorithm +} +func (c *converterImpl) schemaLoadBalancerPrivateNetToHcloudLoadBalancerPrivateNet(source schema.LoadBalancerPrivateNet) LoadBalancerPrivateNet { + var hcloudLoadBalancerPrivateNet LoadBalancerPrivateNet + hcloudNetwork := networkFromInt64(source.Network) + hcloudLoadBalancerPrivateNet.Network = &hcloudNetwork + hcloudLoadBalancerPrivateNet.IP = ipFromString(source.IP) + return hcloudLoadBalancerPrivateNet +} +func (c *converterImpl) schemaLoadBalancerProtectionToHcloudLoadBalancerProtection(source schema.LoadBalancerProtection) LoadBalancerProtection { + var hcloudLoadBalancerProtection LoadBalancerProtection + hcloudLoadBalancerProtection.Delete = source.Delete + return hcloudLoadBalancerProtection +} +func (c *converterImpl) schemaLoadBalancerPublicNetIPv4ToHcloudLoadBalancerPublicNetIPv4(source schema.LoadBalancerPublicNetIPv4) LoadBalancerPublicNetIPv4 { + var hcloudLoadBalancerPublicNetIPv4 LoadBalancerPublicNetIPv4 + hcloudLoadBalancerPublicNetIPv4.IP = ipFromString(source.IP) + hcloudLoadBalancerPublicNetIPv4.DNSPtr = source.DNSPtr + return hcloudLoadBalancerPublicNetIPv4 +} +func (c *converterImpl) schemaLoadBalancerPublicNetIPv6ToHcloudLoadBalancerPublicNetIPv6(source schema.LoadBalancerPublicNetIPv6) LoadBalancerPublicNetIPv6 { + var hcloudLoadBalancerPublicNetIPv6 LoadBalancerPublicNetIPv6 + hcloudLoadBalancerPublicNetIPv6.IP = ipFromString(source.IP) + hcloudLoadBalancerPublicNetIPv6.DNSPtr = source.DNSPtr + return hcloudLoadBalancerPublicNetIPv6 +} +func (c *converterImpl) schemaLoadBalancerPublicNetToHcloudLoadBalancerPublicNet(source schema.LoadBalancerPublicNet) LoadBalancerPublicNet { + var hcloudLoadBalancerPublicNet LoadBalancerPublicNet + hcloudLoadBalancerPublicNet.Enabled = source.Enabled + hcloudLoadBalancerPublicNet.IPv4 = c.schemaLoadBalancerPublicNetIPv4ToHcloudLoadBalancerPublicNetIPv4(source.IPv4) + hcloudLoadBalancerPublicNet.IPv6 = c.schemaLoadBalancerPublicNetIPv6ToHcloudLoadBalancerPublicNetIPv6(source.IPv6) + return hcloudLoadBalancerPublicNet +} +func (c *converterImpl) schemaNetworkProtectionToHcloudNetworkProtection(source schema.NetworkProtection) NetworkProtection { + var hcloudNetworkProtection NetworkProtection + hcloudNetworkProtection.Delete = source.Delete + return hcloudNetworkProtection +} +func (c *converterImpl) schemaPricingServerBackupToHcloudServerBackupPricing(source schema.PricingServerBackup) ServerBackupPricing { + var hcloudServerBackupPricing ServerBackupPricing + hcloudServerBackupPricing.Percentage = source.Percentage + return hcloudServerBackupPricing +} +func (c *converterImpl) schemaPrimaryIPProtectionToHcloudPrimaryIPProtection(source schema.PrimaryIPProtection) PrimaryIPProtection { + var hcloudPrimaryIPProtection PrimaryIPProtection + hcloudPrimaryIPProtection.Delete = source.Delete + return hcloudPrimaryIPProtection +} +func (c *converterImpl) schemaServerProtectionToHcloudServerProtection(source schema.ServerProtection) ServerProtection { + var hcloudServerProtection ServerProtection + hcloudServerProtection.Delete = source.Delete + hcloudServerProtection.Rebuild = source.Rebuild + return hcloudServerProtection +} +func (c *converterImpl) schemaVolumeProtectionToHcloudVolumeProtection(source schema.VolumeProtection) VolumeProtection { + var hcloudVolumeProtection VolumeProtection + hcloudVolumeProtection.Delete = source.Delete + return hcloudVolumeProtection +} +func (c *converterImpl) serverTypePricingFromSchema(source schema.PricingServerTypePrice) ServerTypeLocationPricing { + var hcloudServerTypeLocationPricing ServerTypeLocationPricing + hcloudLocation := locationFromString(source.Location) + hcloudServerTypeLocationPricing.Location = &hcloudLocation + hcloudServerTypeLocationPricing.Hourly = c.PriceFromSchema(source.PriceHourly) + hcloudServerTypeLocationPricing.Monthly = c.PriceFromSchema(source.PriceMonthly) + hcloudServerTypeLocationPricing.IncludedTraffic = source.IncludedTraffic + hcloudServerTypeLocationPricing.PerTBTraffic = c.PriceFromSchema(source.PricePerTBTraffic) + return hcloudServerTypeLocationPricing +} +func (c *converterImpl) timeTimeToTimeTime(source time.Time) time.Time { + return source +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_server_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_server_client_iface.go new file mode 100644 index 0000000000000..f249f7831bde5 --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_server_client_iface.go @@ -0,0 +1,89 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IServerClient ... +type IServerClient interface { + // GetByID retrieves a server by its ID. If the server does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Server, *Response, error) + // GetByName retrieves a server by its name. If the server does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Server, *Response, error) + // Get retrieves a server by its ID if the input can be parsed as an integer, otherwise it + // retrieves a server by its name. If the server does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Server, *Response, error) + // List returns a list of servers for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts ServerListOpts) ([]*Server, *Response, error) + // All returns all servers. + All(ctx context.Context) ([]*Server, error) + // AllWithOpts returns all servers for the given options. + AllWithOpts(ctx context.Context, opts ServerListOpts) ([]*Server, error) + // Create creates a new server. + Create(ctx context.Context, opts ServerCreateOpts) (ServerCreateResult, *Response, error) + // Delete deletes a server. + // + // Deprecated: Use [ServerClient.DeleteWithResult] instead. + Delete(ctx context.Context, server *Server) (*Response, error) + // DeleteWithResult deletes a server and returns the parsed response containing the action. + DeleteWithResult(ctx context.Context, server *Server) (*ServerDeleteResult, *Response, error) + // Update updates a server. + Update(ctx context.Context, server *Server, opts ServerUpdateOpts) (*Server, *Response, error) + // Poweron starts a server. + Poweron(ctx context.Context, server *Server) (*Action, *Response, error) + // Reboot reboots a server. + Reboot(ctx context.Context, server *Server) (*Action, *Response, error) + // Reset resets a server. + Reset(ctx context.Context, server *Server) (*Action, *Response, error) + // Shutdown shuts down a server. + Shutdown(ctx context.Context, server *Server) (*Action, *Response, error) + // Poweroff stops a server. + Poweroff(ctx context.Context, server *Server) (*Action, *Response, error) + // ResetPassword resets a server's password. + ResetPassword(ctx context.Context, server *Server) (ServerResetPasswordResult, *Response, error) + // CreateImage creates an image from a server. + CreateImage(ctx context.Context, server *Server, opts *ServerCreateImageOpts) (ServerCreateImageResult, *Response, error) + // EnableRescue enables rescue mode for a server. + EnableRescue(ctx context.Context, server *Server, opts ServerEnableRescueOpts) (ServerEnableRescueResult, *Response, error) + // DisableRescue disables rescue mode for a server. + DisableRescue(ctx context.Context, server *Server) (*Action, *Response, error) + // Rebuild rebuilds a server. + // + // Deprecated: Use [ServerClient.RebuildWithResult] instead. + Rebuild(ctx context.Context, server *Server, opts ServerRebuildOpts) (*Action, *Response, error) + // RebuildWithResult rebuilds a server. + RebuildWithResult(ctx context.Context, server *Server, opts ServerRebuildOpts) (ServerRebuildResult, *Response, error) + // AttachISO attaches an ISO to a server. + AttachISO(ctx context.Context, server *Server, iso *ISO) (*Action, *Response, error) + // DetachISO detaches the currently attached ISO from a server. + DetachISO(ctx context.Context, server *Server) (*Action, *Response, error) + // EnableBackup enables backup for a server. + // The window parameter is deprecated and will be ignored. + EnableBackup(ctx context.Context, server *Server, window string) (*Action, *Response, error) + // DisableBackup disables backup for a server. + DisableBackup(ctx context.Context, server *Server) (*Action, *Response, error) + // ChangeType changes a server's type. + ChangeType(ctx context.Context, server *Server, opts ServerChangeTypeOpts) (*Action, *Response, error) + // ChangeDNSPtr changes or resets the reverse DNS pointer for a server IP address. + // Pass a nil ptr to reset the reverse DNS pointer to its default value. + ChangeDNSPtr(ctx context.Context, server *Server, ip string, ptr *string) (*Action, *Response, error) + // ChangeProtection changes the resource protection level of a server. + ChangeProtection(ctx context.Context, server *Server, opts ServerChangeProtectionOpts) (*Action, *Response, error) + // RequestConsole requests a WebSocket VNC console. + RequestConsole(ctx context.Context, server *Server) (ServerRequestConsoleResult, *Response, error) + // AttachToNetwork attaches a server to a network. + AttachToNetwork(ctx context.Context, server *Server, opts ServerAttachToNetworkOpts) (*Action, *Response, error) + // DetachFromNetwork detaches a server from a network. + DetachFromNetwork(ctx context.Context, server *Server, opts ServerDetachFromNetworkOpts) (*Action, *Response, error) + // ChangeAliasIPs changes a server's alias IPs in a network. + ChangeAliasIPs(ctx context.Context, server *Server, opts ServerChangeAliasIPsOpts) (*Action, *Response, error) + // GetMetrics obtains metrics for Server. + GetMetrics(ctx context.Context, server *Server, opts ServerGetMetricsOpts) (*ServerMetrics, *Response, error) + AddToPlacementGroup(ctx context.Context, server *Server, placementGroup *PlacementGroup) (*Action, *Response, error) + RemoveFromPlacementGroup(ctx context.Context, server *Server) (*Action, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_server_type_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_server_type_client_iface.go new file mode 100644 index 0000000000000..57c57afa0603d --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_server_type_client_iface.go @@ -0,0 +1,27 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IServerTypeClient ... +type IServerTypeClient interface { + // GetByID retrieves a server type by its ID. If the server type does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*ServerType, *Response, error) + // GetByName retrieves a server type by its name. If the server type does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*ServerType, *Response, error) + // Get retrieves a server type by its ID if the input can be parsed as an integer, otherwise it + // retrieves a server type by its name. If the server type does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*ServerType, *Response, error) + // List returns a list of server types for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts ServerTypeListOpts) ([]*ServerType, *Response, error) + // All returns all server types. + All(ctx context.Context) ([]*ServerType, error) + // AllWithOpts returns all server types for the given options. + AllWithOpts(ctx context.Context, opts ServerTypeListOpts) ([]*ServerType, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_ssh_key_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_ssh_key_client_iface.go new file mode 100644 index 0000000000000..d2c6988d9c3dd --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_ssh_key_client_iface.go @@ -0,0 +1,35 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// ISSHKeyClient ... +type ISSHKeyClient interface { + // GetByID retrieves a SSH key by its ID. If the SSH key does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*SSHKey, *Response, error) + // GetByName retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*SSHKey, *Response, error) + // GetByFingerprint retreives a SSH key by its fingerprint. If the SSH key does not exist, nil is returned. + GetByFingerprint(ctx context.Context, fingerprint string) (*SSHKey, *Response, error) + // Get retrieves a SSH key by its ID if the input can be parsed as an integer, otherwise it + // retrieves a SSH key by its name. If the SSH key does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*SSHKey, *Response, error) + // List returns a list of SSH keys for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts SSHKeyListOpts) ([]*SSHKey, *Response, error) + // All returns all SSH keys. + All(ctx context.Context) ([]*SSHKey, error) + // AllWithOpts returns all SSH keys with the given options. + AllWithOpts(ctx context.Context, opts SSHKeyListOpts) ([]*SSHKey, error) + // Create creates a new SSH key with the given options. + Create(ctx context.Context, opts SSHKeyCreateOpts) (*SSHKey, *Response, error) + // Delete deletes a SSH key. + Delete(ctx context.Context, sshKey *SSHKey) (*Response, error) + // Update updates a SSH key. + Update(ctx context.Context, sshKey *SSHKey, opts SSHKeyUpdateOpts) (*SSHKey, *Response, error) +} diff --git a/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_volume_client_iface.go b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_volume_client_iface.go new file mode 100644 index 0000000000000..28edb7a270eeb --- /dev/null +++ b/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_volume_client_iface.go @@ -0,0 +1,43 @@ +// Code generated by ifacemaker; DO NOT EDIT. + +package hcloud + +import ( + "context" +) + +// IVolumeClient ... +type IVolumeClient interface { + // GetByID retrieves a volume by its ID. If the volume does not exist, nil is returned. + GetByID(ctx context.Context, id int64) (*Volume, *Response, error) + // GetByName retrieves a volume by its name. If the volume does not exist, nil is returned. + GetByName(ctx context.Context, name string) (*Volume, *Response, error) + // Get retrieves a volume by its ID if the input can be parsed as an integer, otherwise it + // retrieves a volume by its name. If the volume does not exist, nil is returned. + Get(ctx context.Context, idOrName string) (*Volume, *Response, error) + // List returns a list of volumes for a specific page. + // + // Please note that filters specified in opts are not taken into account + // when their value corresponds to their zero value or when they are empty. + List(ctx context.Context, opts VolumeListOpts) ([]*Volume, *Response, error) + // All returns all volumes. + All(ctx context.Context) ([]*Volume, error) + // AllWithOpts returns all volumes with the given options. + AllWithOpts(ctx context.Context, opts VolumeListOpts) ([]*Volume, error) + // Create creates a new volume with the given options. + Create(ctx context.Context, opts VolumeCreateOpts) (VolumeCreateResult, *Response, error) + // Delete deletes a volume. + Delete(ctx context.Context, volume *Volume) (*Response, error) + // Update updates a volume. + Update(ctx context.Context, volume *Volume, opts VolumeUpdateOpts) (*Volume, *Response, error) + // AttachWithOpts attaches a volume to a server. + AttachWithOpts(ctx context.Context, volume *Volume, opts VolumeAttachOpts) (*Action, *Response, error) + // Attach attaches a volume to a server. + Attach(ctx context.Context, volume *Volume, server *Server) (*Action, *Response, error) + // Detach detaches a volume from a server. + Detach(ctx context.Context, volume *Volume) (*Action, *Response, error) + // ChangeProtection changes the resource protection level of a volume. + ChangeProtection(ctx context.Context, volume *Volume, opts VolumeChangeProtectionOpts) (*Action, *Response, error) + // Resize changes the size of a volume. + Resize(ctx context.Context, volume *Volume, size int) (*Action, *Response, error) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index eda4da99a7823..45e842c56615f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -764,12 +764,13 @@ github.com/hashicorp/golang-lru/simplelru # github.com/hashicorp/memberlist v0.3.1 ## explicit; go 1.12 github.com/hashicorp/memberlist -# github.com/hetznercloud/hcloud-go v1.59.2 -## explicit; go 1.21 -github.com/hetznercloud/hcloud-go/hcloud -github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation -github.com/hetznercloud/hcloud-go/hcloud/metadata -github.com/hetznercloud/hcloud-go/hcloud/schema +# github.com/hetznercloud/hcloud-go/v2 v2.21.1 +## explicit; go 1.23.0 +github.com/hetznercloud/hcloud-go/v2/hcloud +github.com/hetznercloud/hcloud-go/v2/hcloud/exp/ctxutil +github.com/hetznercloud/hcloud-go/v2/hcloud/internal/instrumentation +github.com/hetznercloud/hcloud-go/v2/hcloud/metadata +github.com/hetznercloud/hcloud-go/v2/hcloud/schema # github.com/huandu/xstrings v1.5.0 ## explicit; go 1.12 github.com/huandu/xstrings