New Upstream Snapshot - golang-github-hetznercloud-hcloud-go
Ready changes
Summary
Merged new upstream version: 1.39.0+git20230208.1.44af6e5+ds (was: 1.35.3).
Diff
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 87533d9..0000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: Continuous Integration
-on: [push, pull_request]
-jobs:
- build:
- name: Build
- runs-on: ubuntu-latest
- strategy:
- matrix:
- go-version: [1.17, 1.18, 1.19]
- steps:
- - name: Set up Go ${{ matrix.go-version }}
- uses: actions/setup-go@v2
- with:
- go-version: ${{ matrix.go-version }}
- - name: Check out code into the Go module directory
- uses: actions/checkout@v1
- - name: Run tests
- run: go test -v ./...
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
deleted file mode 100644
index 88bb867..0000000
--- a/.github/workflows/golangci-lint.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: golangci-lint
-on:
- push:
- tags:
- - v*
- branches:
- - master
- - main
- pull_request:
-jobs:
- golangci:
- name: lint
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: golangci-lint
- uses: golangci/golangci-lint-action@v2
- with:
- # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
- version: latest
-
- # Optional: working directory, useful for monorepos
- # working-directory: somedir
-
- # Optional: golangci-lint command line arguments.
- # args: --issues-exit-code=0
-
- # Optional: show only new issues if it's a pull request. The default value is `false`.
- # only-new-issues: true
-
- # Optional: if set to true then the action will use pre-installed Go
- # skip-go-installation: true
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 69e16b3..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Release Changelog
-on:
- push:
- tags:
- - '*'
-jobs:
- build:
- name: Build
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
- - name: Set up Go
- uses: actions/setup-go@v2
- with:
- go-version: 1.19
- - name: Run GoReleaser
- uses: goreleaser/goreleaser-action@v2
- with:
- distribution: goreleaser
- version: latest
- args: release --rm-dist
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 849ddff..0000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-dist/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index f95e854..0000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-stages:
- - test
-
-variables:
- GIT_SUBMODULE_STRATEGY: normal
-
-test:golangci-lint:
- stage: test
- image: golangci/golangci-lint:latest
- script:
- - golangci-lint run -v
- except:
- - tags
- - master
- tags:
- - hc-bladerunner
-
-test:tests:
- stage: test
- image: golang:1.18
- script:
- - go test -v -race ./...
- except:
- - tags
- - master
- tags:
- - hc-bladerunner
diff --git a/.golangci.yaml b/.golangci.yaml
index 3e86fc8..ef87e03 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -4,6 +4,11 @@ linters-settings:
exclude: ./.errcheck_excludes.txt
exhaustive:
default-signifies-exhaustive: true
+ gci:
+ sections:
+ - standard
+ - default
+ - prefix(github.com/hetznercloud)
gomodguard:
blocked:
modules:
@@ -27,13 +32,15 @@ linters:
disable-all: true
enable:
- bodyclose
- - deadcode
- depguard
- errcheck
+ - errname
- exhaustive
+ - exportloopref
+ - gci
- gocritic
+ - godot
- goimports
- - golint
- gomodguard
- gosec
- gosimple
@@ -41,14 +48,11 @@ linters:
- ineffassign
- misspell
- prealloc
- - rowserrcheck
- - scopelint
+ - revive
- staticcheck
- - structcheck
- typecheck
- unparam
- unused
- - varcheck
- whitespace
issues:
@@ -56,8 +60,4 @@ issues:
- path: _test\.go
linters:
- gosec
- - scopelint
- errcheck
- - linters:
- - gosec
- text: "G204:"
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index f1f8e5d..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-builds:
- - skip: true
-changelog:
- sort: asc
- filters:
- exclude:
- - '^docs:'
- - '^test:'
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..c4281bf
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,337 @@
+# Changelog
+
+## [1.39.0](https://github.com/hetznercloud/hcloud-go/compare/v1.38.0...v1.39.0) (2022-12-29)
+
+
+### Features
+
+* Use generics to get pointers to types ([#219](https://github.com/hetznercloud/hcloud-go/issues/219)) ([a5cd797](https://github.com/hetznercloud/hcloud-go/commit/a5cd79782dc849b3137e46ada2da6b319d4093c8))
+
+
+### Bug Fixes
+
+* deprecate PricingPrimaryIPTypePrice.Datacenter for Location ([#222](https://github.com/hetznercloud/hcloud-go/issues/222)) ([e0e5a1e](https://github.com/hetznercloud/hcloud-go/commit/e0e5a1e08fd7c0864fd94a787ee86714b5e9afc5))
+
+## v1.38.0
+
+### What's Changed
+* feat(network): add new Network Zone us-west by @apricote in https://github.com/hetznercloud/hcloud-go/pull/217
+* chore: prepare v1.38.0 by @apricote in https://github.com/hetznercloud/hcloud-go/pull/218
+
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.37.0...v1.38.0
+
+## v1.37.0
+
+### What's Changed
+* PrimaryIPClient Add AllWithOpts by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/214
+* fix: error when updating IPv6 Primary IP by @apricote in https://github.com/hetznercloud/hcloud-go/pull/215
+
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.36.0...v1.37.0
+
+## v1.36.0
+
+### What's Changed
+* feat: add ServerClient.DeleteWithResult method by @apricote in https://github.com/hetznercloud/hcloud-go/pull/213
+
+### New Contributors
+* @apricote made their first contribution in https://github.com/hetznercloud/hcloud-go/pull/213
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.35.3...v1.36.0
+
+## v1.35.3
+
+### What's Changed
+* Drop support for Go < 1.17 and add official tests on go 1.19 by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/211
+* Stop automatic retrying on RateLimitExceeded by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/210
+
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.35.2...v1.35.3
+
+## v1.35.2
+
+### What's Changed
+* Allow empty labels by @4ND3R50N in https://github.com/hetznercloud/hcloud-go/pull/207
+
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.35.1...v1.35.2
+
+## v1.35.1
+
+### What's Changed
+* Accept no primary IPs with server create with StartAfterCreate = false by @4ND3R50N in https://github.com/hetznercloud/hcloud-go/pull/205
+
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.35.0...v1.35.1
+
+## v1.35.0
+
+### What's Changed
+* Catch invalid token values and error out without value exposure by @NotTheEvilOne in https://github.com/hetznercloud/hcloud-go/pull/194
+* Remove ServerRescueTypeFreeBSD64 by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/203
+* Add Primary IP Support by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/204
+
+### New Contributors
+* @NotTheEvilOne made their first contribution in https://github.com/hetznercloud/hcloud-go/pull/194
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.34.0...v1.35.0
+
+## v1.34.0
+
+### What's Changed
+* Test on Go 1.18 by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/202
+* Add support for sorting the response of all list calls by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/201
+* Set UsePrivateIP for targets when creating a LoadBalancer by @hakman in https://github.com/hetznercloud/hcloud-go/pull/198
+
+### New Contributors
+* @hakman made their first contribution in https://github.com/hetznercloud/hcloud-go/pull/198
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.33.2...v1.34.0
+
+## v1.33.2
+
+### What's Changed
+* Add constant for resource locked error code by @patrickschaffrath in https://github.com/hetznercloud/hcloud-go/pull/189
+* Fix metadata client error detection by @choffmeister in https://github.com/hetznercloud/hcloud-go/pull/193
+* Add labels.go to validate resource labels by @4ND3R50N in https://github.com/hetznercloud/hcloud-go/pull/197
+
+### New Contributors
+* @patrickschaffrath made their first contribution in https://github.com/hetznercloud/hcloud-go/pull/189
+* @choffmeister made their first contribution in https://github.com/hetznercloud/hcloud-go/pull/193
+* @4ND3R50N made their first contribution in https://github.com/hetznercloud/hcloud-go/pull/197
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.33.1...v1.33.2
+
+## v1.33.1
+
+### Changelog
+
+41fef2f Add constants for new firewall error code
+
+## v1.33.0
+
+### What's Changed
+* Add us-east network zone by @LKaemmerling in https://github.com/hetznercloud/hcloud-go/pull/187
+
+
+**Full Changelog**: https://github.com/hetznercloud/hcloud-go/compare/v1.32.0...v1.33.0
+
+## v1.32.0
+
+### Changelog
+
+785896c Add Metadata Client (#184)
+7778143 Bump version to 1.32.0
+eabe683 Make it possible to instrument the hcloud-go (#185)
+
+## v1.31.1
+
+### Changelog
+
+1cde0d7 Add RDNS client (#183)
+
+## v1.31.0
+
+### Changelog
+
+0656bf9 Add support for Load Balancer DNS PTRs (#182)
+9218970 Bump hcloud.Version
+ebf9f25 Test on/with go 1.17 (#181)
+
+## v1.30.0
+
+### Changelog
+
+592b198 Add new Floating IP Pricing structure (#180)
+c43897a Bump hcloud.Version
+ab0ebb2 Placement groups (#179)
+
+## v1.29.1
+
+### Changelog
+
+e951e99 Fix firewall rule description
+
+## v1.29.0
+
+### Changelog
+
+e3eca12 Add description field to firewall rules (#177)
+
+## v1.28.0
+
+### Changelog
+
+ae5e1b8 Add goreleaser (#175)
+4cf75f4 Add support for app images (#176)
+
+## v1.27.0
+
+Add support for firewall protocols ESP and GRE (#173)
+
+## v1.26.2
+
+- Fix AppliedTo Field in FirewallCreateRequest
+- Add `deleted` and `IsDeleted()` to `Image` (https://github.com/hetznercloud/hcloud-go/pull/172)
+
+## v1.26.1
+
+- Fix validation error caused by firewall label selectors (https://github.com/hetznercloud/hcloud-go/pull/171)
+
+## v1.26.0
+
+- Add Firewall Resource Label Selector (#169)
+
+## v1.25.0
+
+* Support Hetzner Cloud managed Certificates (#167)
+
+## v1.23.1
+* Add removed `ErrorCodeServerAlreadyAttached` again
+
+## v1.23.0
+
+* Add missing constants for all resource specific error codes
+* Expose metrics for Servers and Load Balancers
+* Add support for vSwitch Subnetworks
+
+## v1.22.0
+
+* Add `PrimaryDiskSize` Field to `Server`
+
+## v1.21.1
+
+* Don't send `Authorization` Header when `WithToken` was not called
+
+## v1.21.0
+
+* Add `IncludeDeprecated` Field to `ImageListOpts`
+
+## v1.20.0
+
+* Add support for Load Balancer Label Selector targets
+* Add support for Load Balancer IP targets
+
+## v1.19.0
+
+* Fix nil pointer dereference when creating a Load Balancer with HTTP(S)
+ service and not providing HTTP-specific options
+* Add `IncludedTraffic`, `OutgoingTraffic` and `IngoingTraffic` fields to `LoadBalancer`
+* Add `ChangeType()` method to the Load Balancer client
+* Fix retrying of requests that contain a body
+
+## v1.18.2
+
+* Retry API requests on conflict error
+
+## v1.18.1
+
+* Make all `GetByName` methods return `nil` when an empty name is provided
+* Clarify that filters specified in options for List() calls are not taken
+ into account when their value corresponds to their zero value or when
+ they are empty.
+
+## v1.18.0
+
+* Add `Status` field to `Volume`
+* Add subnet type `cloud`
+* Add `WithHTTPClient` option to specify a custom `http.Client`
+* Add API for requesting a VNC console
+* Add support for load balancers and certificates (beta)
+
+## v1.17.0
+
+* Add `Created` field to `SSHKey`
+
+## v1.16.0
+
+* Make IP range optional when adding a subnet to a network
+* Add support for names to Floating IPs
+
+## v1.15.1
+
+* Rename `MacAddress` to `MACAddress` on `ServerPrivateNet`
+
+## v1.15.0
+
+* Add `MacAddress` field to `ServerPrivateNet`
+* Add `WithDebugWriter()` client option to provide an `io.Writer` to write debug output to
+
+## v1.14.0
+
+* Add `Created` field to `FloatingIP`
+* Add support for networks
+
+## v1.13.0
+
+* Add missing fields to `*ListOpts` structs
+* Fix error handling in `WatchProgress()`
+* Add support for filtering volumes, images, and servers by status
+
+## v1.12.0
+
+* Add missing constants for all [documented error codes](https://docs.hetzner.cloud/#overview-errors)
+* Add support for automounting volumes
+* Add support for attaching volumes when creating a server
+
+## v1.11.0
+
+* Add `NextActions` to `ServerCreateResult` and `VolumeCreateResult`
+
+## v1.10.0
+
+* Add `WithApplication()` client option to provide an application name and version
+ that will be included in the `User-Agent` HTTP header
+* Add support for volumes
+
+## v1.9.0
+
+* Add `AllWithOpts()` to server, Floating IP, image, and SSH key client
+* Expose labels of servers, Floating IPs, images, and SSH Keys
+
+## v1.8.0
+
+* Add `WithPollInterval()` option to `Client` which allows to specify the polling interval
+ ([issue #92](https://github.com/hetznercloud/hcloud-go/issues/92))
+* Add `CPUType` field to `ServerType` ([issue #91](https://github.com/hetznercloud/hcloud-go/pull/91))
+
+## v1.7.0
+
+* Add `Deprecated ` field to `Image` ([issue #88](https://github.com/hetznercloud/hcloud-go/issues/88))
+* Add `StartAfterCreate` flag to `ServerCreateOpts` ([issue #87](https://github.com/hetznercloud/hcloud-go/issues/87))
+* Fix enum types ([issue #89](https://github.com/hetznercloud/hcloud-go/issues/89))
+
+## v1.6.0
+
+* Add `ChangeProtection()` to server, Floating IP, and image client
+* Expose protection of servers, Floating IPs, and images
+
+## v1.5.0
+
+* Add `GetByFingerprint()` to SSH key client
+
+## v1.4.0
+
+* Retry all calls that triggered the API ratelimit
+* Slow down `WatchProgress()` in action client from 100ms polling interval to 500ms
+
+## v1.3.1
+
+* Make clients using the old error code for ratelimiting work as expected
+ ([issue #73](https://github.com/hetznercloud/hcloud-go/issues/73))
+
+## v1.3.0
+
+* Support passing user data on server creation ([issue #70](https://github.com/hetznercloud/hcloud-go/issues/70))
+* Fix leaking response body by not closing it ([issue #68](https://github.com/hetznercloud/hcloud-go/issues/68))
+
+## v1.2.0
+
+* Add `WatchProgress()` to action client
+* Use correct error code for ratelimit error (deprecated
+ `ErrorCodeLimitReached`, added `ErrorCodeRateLimitExceeded`)
+
+## v1.1.0
+
+* Add `Image` field to `Server`
diff --git a/CHANGES.md b/CHANGES.md
deleted file mode 100644
index efa8015..0000000
--- a/CHANGES.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# Changes
-
-As of release v1.24.0 we moved the release notes to Github Releases: https://github.com/hetznercloud/hcloud-go/releases
-
-## v1.23.1
-* Add removed `ErrorCodeServerAlreadyAttached` again
-
-## v1.23.0
-
-* Add missing constants for all resource specific error codes
-* Expose metrics for Servers and Load Balancers
-* Add support for vSwitch Subnetworks
-
-## v1.22.0
-
-* Add `PrimaryDiskSize` Field to `Server`
-
-## v1.21.1
-
-* Don't send `Authorization` Header when `WithToken` was not called
-
-## v1.21.0
-
-* Add `IncludeDeprecated` Field to `ImageListOpts`
-
-## v1.20.0
-
-* Add support for Load Balancer Label Selector targets
-* Add support for Load Balancer IP targets
-
-## v1.19.0
-
-* Fix nil pointer dereference when creating a Load Balancer with HTTP(S)
- service and not providing HTTP-specific options
-* Add `IncludedTraffic`, `OutgoingTraffic` and `IngoingTraffic` fields to `LoadBalancer`
-* Add `ChangeType()` method to the Load Balancer client
-* Fix retrying of requests that contain a body
-
-## v1.18.2
-
-* Retry API requests on conflict error
-
-## v1.18.1
-
-* Make all `GetByName` methods return `nil` when an empty name is provided
-* Clarify that filters specified in options for List() calls are not taken
- into account when their value corresponds to their zero value or when
- they are empty.
-
-## v1.18.0
-
-* Add `Status` field to `Volume`
-* Add subnet type `cloud`
-* Add `WithHTTPClient` option to specify a custom `http.Client`
-* Add API for requesting a VNC console
-* Add support for load balancers and certificates (beta)
-
-## v1.17.0
-
-* Add `Created` field to `SSHKey`
-
-## v1.16.0
-
-* Make IP range optional when adding a subnet to a network
-* Add support for names to Floating IPs
-
-## v1.15.1
-
-* Rename `MacAddress` to `MACAddress` on `ServerPrivateNet`
-
-## v1.15.0
-
-* Add `MacAddress` field to `ServerPrivateNet`
-* Add `WithDebugWriter()` client option to provide an `io.Writer` to write debug output to
-
-## v1.14.0
-
-* Add `Created` field to `FloatingIP`
-* Add support for networks
-
-## v1.13.0
-
-* Add missing fields to `*ListOpts` structs
-* Fix error handling in `WatchProgress()`
-* Add support for filtering volumes, images, and servers by status
-
-## v1.12.0
-
-* Add missing constants for all [documented error codes](https://docs.hetzner.cloud/#overview-errors)
-* Add support for automounting volumes
-* Add support for attaching volumes when creating a server
-
-## v1.11.0
-
-* Add `NextActions` to `ServerCreateResult` and `VolumeCreateResult`
-
-## v1.10.0
-
-* Add `WithApplication()` client option to provide an application name and version
- that will be included in the `User-Agent` HTTP header
-* Add support for volumes
-
-## v1.9.0
-
-* Add `AllWithOpts()` to server, Floating IP, image, and SSH key client
-* Expose labels of servers, Floating IPs, images, and SSH Keys
-
-## v1.8.0
-
-* Add `WithPollInterval()` option to `Client` which allows to specify the polling interval
- ([issue #92](https://github.com/hetznercloud/hcloud-go/issues/92))
-* Add `CPUType` field to `ServerType` ([issue #91](https://github.com/hetznercloud/hcloud-go/pull/91))
-
-## v1.7.0
-
-* Add `Deprecated ` field to `Image` ([issue #88](https://github.com/hetznercloud/hcloud-go/issues/88))
-* Add `StartAfterCreate` flag to `ServerCreateOpts` ([issue #87](https://github.com/hetznercloud/hcloud-go/issues/87))
-* Fix enum types ([issue #89](https://github.com/hetznercloud/hcloud-go/issues/89))
-
-## v1.6.0
-
-* Add `ChangeProtection()` to server, Floating IP, and image client
-* Expose protection of servers, Floating IPs, and images
-
-## v1.5.0
-
-* Add `GetByFingerprint()` to SSH key client
-
-## v1.4.0
-
-* Retry all calls that triggered the API ratelimit
-* Slow down `WatchProgress()` in action client from 100ms polling interval to 500ms
-
-## v1.3.1
-
-* Make clients using the old error code for ratelimiting work as expected
- ([issue #73](https://github.com/hetznercloud/hcloud-go/issues/73))
-
-## v1.3.0
-
-* Support passing user data on server creation ([issue #70](https://github.com/hetznercloud/hcloud-go/issues/70))
-* Fix leaking response body by not closing it ([issue #68](https://github.com/hetznercloud/hcloud-go/issues/68))
-
-## v1.2.0
-
-* Add `WatchProgress()` to action client
-* Use correct error code for ratelimit error (deprecated
- `ErrorCodeLimitReached`, added `ErrorCodeRateLimitExceeded`)
-
-## v1.1.0
-
-* Add `Image` field to `Server`
diff --git a/README.md b/README.md
index 2263cb9..238c6ec 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,14 @@ func main() {
}
```
+## Go Version Support
+
+The library supports the latest two Go minor versions, e.g. at the time Go 1.19 is released, it supports Go 1.18 and 1.19.
+
+This matches the official [Go Release Policy](https://go.dev/doc/devel/release#policy).
+
+When the minimum required Go version is changed, it is announced in the release notes for that version.
+
## License
MIT license
diff --git a/debian/changelog b/debian/changelog
index a894207..1e29ea4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-github-hetznercloud-hcloud-go (1.39.0+git20230208.1.44af6e5+ds-1) UNRELEASED; urgency=low
+
+ * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 08 Feb 2023 23:46:47 -0000
+
golang-github-hetznercloud-hcloud-go (1.35.3-1) unstable; urgency=medium
* New upstream release
diff --git a/go.mod b/go.mod
index 33a3399..d685473 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/hetznercloud/hcloud-go
-go 1.18
+go 1.19
require (
github.com/google/go-cmp v0.5.5
diff --git a/hcloud/action.go b/hcloud/action.go
index 622f7bf..e915d75 100644
--- a/hcloud/action.go
+++ b/hcloud/action.go
@@ -181,7 +181,24 @@ func (c *ActionClient) AllWithOpts(ctx context.Context, opts ActionListOpts) ([]
return allActions, nil
}
-// WatchOverallProgress watches several actions' progress until they complete with success or 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 [WithPollBackoffFunc] of the [Client] to wait
+// until sending the next request.
func (c *ActionClient) WatchOverallProgress(ctx context.Context, actions []*Action) (<-chan int, <-chan error) {
errCh := make(chan error, len(actions))
progressCh := make(chan int)
@@ -196,15 +213,15 @@ func (c *ActionClient) WatchOverallProgress(ctx context.Context, actions []*Acti
watchIDs[action.ID] = struct{}{}
}
- ticker := time.NewTicker(c.client.pollInterval)
- defer ticker.Stop()
+ retries := 0
+
for {
select {
case <-ctx.Done():
errCh <- ctx.Err()
return
- case <-ticker.C:
- break
+ case <-time.After(c.client.pollBackoffFunc(retries)):
+ retries++
}
opts := ActionListOpts{}
@@ -241,7 +258,24 @@ func (c *ActionClient) WatchOverallProgress(ctx context.Context, actions []*Acti
return progressCh, errCh
}
-// WatchProgress watches one action's progress until it completes with success or 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 [WithPollBackoffFunc] of the [Client] to wait until
+// sending the next request.
func (c *ActionClient) WatchProgress(ctx context.Context, action *Action) (<-chan int, <-chan error) {
errCh := make(chan error, 1)
progressCh := make(chan int)
@@ -250,16 +284,15 @@ func (c *ActionClient) WatchProgress(ctx context.Context, action *Action) (<-cha
defer close(errCh)
defer close(progressCh)
- ticker := time.NewTicker(c.client.pollInterval)
- defer ticker.Stop()
+ retries := 0
for {
select {
case <-ctx.Done():
errCh <- ctx.Err()
return
- case <-ticker.C:
- break
+ case <-time.After(c.client.pollBackoffFunc(retries)):
+ retries++
}
a, _, err := c.GetByID(ctx, action.ID)
diff --git a/hcloud/action_test.go b/hcloud/action_test.go
index 28e32f7..660f3de 100644
--- a/hcloud/action_test.go
+++ b/hcloud/action_test.go
@@ -3,7 +3,9 @@ package hcloud
import (
"context"
"encoding/json"
+ "errors"
"net/http"
+ "reflect"
"testing"
"time"
@@ -164,6 +166,126 @@ func TestActionClientAll(t *testing.T) {
}
}
+func TestActionClientWatchOverallProgress(t *testing.T) {
+ env := newTestEnv()
+ defer env.Teardown()
+
+ callCount := 0
+
+ env.Mux.HandleFunc("/actions", func(w http.ResponseWriter, r *http.Request) {
+ callCount++
+ var actions []schema.Action
+
+ switch callCount {
+ case 1:
+ actions = []schema.Action{
+ {
+ ID: 1,
+ Status: "running",
+ Progress: 50,
+ },
+ {
+ ID: 2,
+ Status: "running",
+ Progress: 50,
+ },
+ }
+ case 2:
+ actions = []schema.Action{
+ {
+ ID: 1,
+ Status: "running",
+ Progress: 75,
+ },
+ {
+ ID: 2,
+ Status: "error",
+ Progress: 100,
+ Error: &schema.ActionError{
+ Code: "action_failed",
+ Message: "action failed",
+ },
+ },
+ }
+ case 3:
+ actions = []schema.Action{
+ {
+ ID: 1,
+ Status: "success",
+ Progress: 100,
+ },
+ }
+ default:
+ t.Errorf("unexpected number of calls to the test server: %v", callCount)
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ _ = json.NewEncoder(w).Encode(struct {
+ Actions []schema.Action `json:"actions"`
+ Meta schema.Meta `json:"meta"`
+ }{
+ Actions: actions,
+ Meta: schema.Meta{
+ Pagination: &schema.MetaPagination{
+ Page: 1,
+ LastPage: 1,
+ PerPage: len(actions),
+ TotalEntries: len(actions),
+ },
+ },
+ })
+ })
+
+ actions := []*Action{
+ {
+ ID: 1,
+ Status: ActionStatusRunning,
+ },
+ {
+ ID: 2,
+ Status: ActionStatusRunning,
+ },
+ }
+
+ ctx := context.Background()
+ progressCh, errCh := env.Client.Action.WatchOverallProgress(ctx, actions)
+ progressUpdates := []int{}
+ errs := []error{}
+
+ moreProgress, moreErrors := true, true
+
+ for moreProgress || moreErrors {
+ var progress int
+ var err error
+
+ select {
+ case progress, moreProgress = <-progressCh:
+ if moreProgress {
+ progressUpdates = append(progressUpdates, progress)
+ }
+ case err, moreErrors = <-errCh:
+ if moreErrors {
+ errs = append(errs, err)
+ }
+ }
+ }
+
+ if len(errs) != 1 {
+ t.Fatalf("expected to receive one error: %v", errs)
+ }
+
+ err := errs[0]
+
+ if e, ok := errors.Unwrap(err).(ActionError); !ok || e.Code != "action_failed" {
+ t.Fatalf("expected hcloud.Error, but got: %#v", err)
+ }
+
+ expectedProgressUpdates := []int{50}
+ if !reflect.DeepEqual(progressUpdates, expectedProgressUpdates) {
+ t.Fatalf("expected progresses %v but received %v", expectedProgressUpdates, progressUpdates)
+ }
+}
+
func TestActionClientWatchProgress(t *testing.T) {
env := newTestEnv()
defer env.Teardown()
diff --git a/hcloud/certificate.go b/hcloud/certificate.go
index 04334de..6278552 100644
--- a/hcloud/certificate.go
+++ b/hcloud/certificate.go
@@ -31,10 +31,10 @@ const (
CertificateStatusTypePending CertificateStatusType = "pending"
CertificateStatusTypeFailed CertificateStatusType = "failed"
- // only in issuance
+ // only in issuance.
CertificateStatusTypeCompleted CertificateStatusType = "completed"
- // only in renewal
+ // only in renewal.
CertificateStatusTypeScheduled CertificateStatusType = "scheduled"
CertificateStatusTypeUnavailable CertificateStatusType = "unavailable"
)
diff --git a/hcloud/certificate_test.go b/hcloud/certificate_test.go
index 055351a..003bcb5 100644
--- a/hcloud/certificate_test.go
+++ b/hcloud/certificate_test.go
@@ -405,7 +405,7 @@ func TestCertificateClientUpdate(t *testing.T) {
t.Fatal(err)
}
expectedReqBody := schema.CertificateUpdateRequest{
- Name: String("test"),
+ Name: Ptr("test"),
Labels: func() *map[string]string {
labels := map[string]string{"key": "value"}
return &labels
diff --git a/hcloud/client.go b/hcloud/client.go
index 792be9b..f3b5a83 100644
--- a/hcloud/client.go
+++ b/hcloud/client.go
@@ -15,10 +15,11 @@ import (
"strings"
"time"
- "github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation"
- "github.com/hetznercloud/hcloud-go/hcloud/schema"
"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"
)
// Endpoint is the base URL of the API.
@@ -42,7 +43,10 @@ func ConstantBackoff(d time.Duration) BackoffFunc {
}
// ExponentialBackoff returns a BackoffFunc which implements an exponential
-// backoff using the formula: b^retries * d
+// backoff.
+// It uses the formula:
+//
+// b^retries * d
func ExponentialBackoff(b float64, d time.Duration) BackoffFunc {
return func(retries int) time.Duration {
return time.Duration(math.Pow(b, float64(retries))) * d
@@ -54,8 +58,8 @@ type Client struct {
endpoint string
token string
tokenValid bool
- pollInterval time.Duration
backoffFunc BackoffFunc
+ pollBackoffFunc BackoffFunc
httpClient *http.Client
applicationName string
applicationVersion string
@@ -102,15 +106,31 @@ func WithToken(token string) ClientOption {
}
}
-// WithPollInterval configures a Client to use the specified interval when polling
-// from the API.
+// WithPollInterval configures a Client to use the specified interval when
+// 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
+// migrate your code, replace your usage like this:
+//
+// // before
+// hcloud.WithPollInterval(2 * time.Second)
+// // now
+// hcloud.WithPollBackoffFunc(hcloud.ConstantBackoff(2 * time.Second))
func WithPollInterval(pollInterval time.Duration) ClientOption {
+ return WithPollBackoffFunc(ConstantBackoff(pollInterval))
+}
+
+// WithPollBackoffFunc configures a Client to use the specified backoff
+// function when polling from the API.
+func WithPollBackoffFunc(f BackoffFunc) ClientOption {
return func(client *Client) {
- client.pollInterval = pollInterval
+ client.backoffFunc = f
}
}
// WithBackoffFunc configures a Client to use the specified backoff function.
+// The backoff function is used for retrying HTTP requests.
func WithBackoffFunc(f BackoffFunc) ClientOption {
return func(client *Client) {
client.backoffFunc = f
@@ -152,11 +172,11 @@ 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),
- pollInterval: 500 * time.Millisecond,
+ endpoint: Endpoint,
+ tokenValid: true,
+ httpClient: &http.Client{},
+ backoffFunc: ExponentialBackoff(2, 500*time.Millisecond),
+ pollBackoffFunc: ConstantBackoff(500 * time.Millisecond),
}
for _, option := range options {
diff --git a/hcloud/client_test.go b/hcloud/client_test.go
index e6d804b..e4df032 100644
--- a/hcloud/client_test.go
+++ b/hcloud/client_test.go
@@ -35,6 +35,7 @@ func newTestEnv() testEnv {
WithEndpoint(server.URL),
WithToken("token"),
WithBackoffFunc(func(_ int) time.Duration { return 0 }),
+ WithPollBackoffFunc(func(r int) time.Duration { return 0 }),
)
return testEnv{
Server: server,
diff --git a/hcloud/error.go b/hcloud/error.go
index c15581b..ff04d07 100644
--- a/hcloud/error.go
+++ b/hcloud/error.go
@@ -28,14 +28,14 @@ const (
ErrorCodeResourceLocked ErrorCode = "resource_locked" // The resource is locked. The caller should contact support
ErrorUnsupportedError ErrorCode = "unsupported_error" // The given resource does not support this
- // Server related error codes
+ // Server related error codes.
ErrorCodeInvalidServerType ErrorCode = "invalid_server_type" // The server type does not fit for the given server or is deprecated
ErrorCodeServerNotStopped ErrorCode = "server_not_stopped" // The action requires a stopped server
ErrorCodeNetworksOverlap ErrorCode = "networks_overlap" // The network IP range overlaps with one of the server networks
ErrorCodePlacementError ErrorCode = "placement_error" // An error during the placement occurred
ErrorCodeServerAlreadyAttached ErrorCode = "server_already_attached" // The server is already attached to the resource
- // Load Balancer related error codes
+ // Load Balancer related error codes.
ErrorCodeIPNotOwned ErrorCode = "ip_not_owned" // The IP you are trying to add as a target is not owned by the Project owner
ErrorCodeSourcePortAlreadyUsed ErrorCode = "source_port_already_used" // The source port you are trying to add is already in use
ErrorCodeCloudResourceIPNotAllowed ErrorCode = "cloud_resource_ip_not_allowed" // The IP you are trying to add as a target belongs to a Hetzner Cloud resource
@@ -46,16 +46,16 @@ const (
ErrorCodeTargetsWithoutUsePrivateIP ErrorCode = "targets_without_use_private_ip" // The Load Balancer has targets that use the public IP instead of the private IP
ErrorCodeLoadBalancerNotAttachedToNetwork ErrorCode = "load_balancer_not_attached_to_network" // The Load Balancer is not attached to a network
- // Network related error codes
+ // Network related error codes.
ErrorCodeIPNotAvailable ErrorCode = "ip_not_available" // The provided Network IP is not available
ErrorCodeNoSubnetAvailable ErrorCode = "no_subnet_available" // No Subnet or IP is available for the Load Balancer/Server within the network
ErrorCodeVSwitchAlreadyUsed ErrorCode = "vswitch_id_already_used" // The given Robot vSwitch ID is already registered in another network
- // Volume related error codes
+ // Volume related error codes.
ErrorCodeNoSpaceLeftInLocation ErrorCode = "no_space_left_in_location" // There is no volume space left in the given location
ErrorCodeVolumeAlreadyAttached ErrorCode = "volume_already_attached" // Volume is already attached to a server, detach first
- // Firewall related error codes
+ // Firewall related error codes.
ErrorCodeFirewallAlreadyApplied ErrorCode = "firewall_already_applied" // Firewall was already applied on resource
ErrorCodeFirewallAlreadyRemoved ErrorCode = "firewall_already_removed" // Firewall was already removed from the resource
ErrorCodeIncompatibleNetworkType ErrorCode = "incompatible_network_type" // The Network type is incompatible for the given resource
@@ -63,7 +63,7 @@ const (
ErrorCodeServerAlreadyAdded ErrorCode = "server_already_added" // Server added more than one time to resource
ErrorCodeFirewallResourceNotFound ErrorCode = "firewall_resource_not_found" // Resource a firewall should be attached to / detached from not found
- // Certificate related error codes
+ // Certificate related error codes.
ErrorCodeCAARecordDoesNotAllowCA ErrorCode = "caa_record_does_not_allow_ca" // CAA record does not allow certificate authority
ErrorCodeCADNSValidationFailed ErrorCode = "ca_dns_validation_failed" // Certificate Authority: DNS validation failed
ErrorCodeCATooManyAuthorizationsFailedRecently ErrorCode = "ca_too_many_authorizations_failed_recently" // Certificate Authority: Too many authorizations failed recently
diff --git a/hcloud/firewall_test.go b/hcloud/firewall_test.go
index bdda89d..3353148 100644
--- a/hcloud/firewall_test.go
+++ b/hcloud/firewall_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+
"github.com/hetznercloud/hcloud-go/hcloud/schema"
)
@@ -281,7 +282,7 @@ func TestFirewallClientUpdate(t *testing.T) {
t.Fatal(err)
}
expectedReqBody := schema.FirewallUpdateRequest{
- Name: String("test"),
+ Name: Ptr("test"),
Labels: func() *map[string]string {
labels := map[string]string{"key": "value"}
return &labels
diff --git a/hcloud/floating_ip.go b/hcloud/floating_ip.go
index b180409..e2643a6 100644
--- a/hcloud/floating_ip.go
+++ b/hcloud/floating_ip.go
@@ -32,7 +32,7 @@ type FloatingIP struct {
}
// DNSPtrForIP returns the reverse DNS pointer of the IP address.
-// Deprecated: Use GetDNSPtrForIP instead
+// Deprecated: Use GetDNSPtrForIP instead.
func (f *FloatingIP) DNSPtrForIP(ip net.IP) string {
return f.DNSPtr[ip.String()]
}
@@ -241,10 +241,10 @@ func (c *FloatingIPClient) Create(ctx context.Context, opts FloatingIPCreateOpts
Name: opts.Name,
}
if opts.HomeLocation != nil {
- reqBody.HomeLocation = String(opts.HomeLocation.Name)
+ reqBody.HomeLocation = Ptr(opts.HomeLocation.Name)
}
if opts.Server != nil {
- reqBody.Server = Int(opts.Server.ID)
+ reqBody.Server = Ptr(opts.Server.ID)
}
if opts.Labels != nil {
reqBody.Labels = &opts.Labels
diff --git a/hcloud/floating_ip_test.go b/hcloud/floating_ip_test.go
index eb1709e..b3494a1 100644
--- a/hcloud/floating_ip_test.go
+++ b/hcloud/floating_ip_test.go
@@ -247,7 +247,7 @@ func TestFloatingIPClientCreate(t *testing.T) {
opts := FloatingIPCreateOpts{
Type: FloatingIPTypeIPv4,
- Description: String("test"),
+ Description: Ptr("test"),
HomeLocation: &Location{Name: "test"},
Server: &Server{ID: 1},
Labels: map[string]string{"key": "value"},
@@ -292,10 +292,10 @@ func TestFloatingIPClientCreateWithName(t *testing.T) {
opts := FloatingIPCreateOpts{
Type: FloatingIPTypeIPv4,
- Description: String("test"),
+ Description: Ptr("test"),
HomeLocation: &Location{Name: "test"},
Server: &Server{ID: 1},
- Name: String("MyFloatingIP"),
+ Name: Ptr("MyFloatingIP"),
Labels: map[string]string{"key": "value"},
}
@@ -564,7 +564,7 @@ func TestFloatingIPClientChangeProtection(t *testing.T) {
})
opts := FloatingIPChangeProtectionOpts{
- Delete: Bool(true),
+ Delete: Ptr(true),
}
action, _, err := env.Client.FloatingIP.ChangeProtection(ctx, floatingIP, opts)
if err != nil {
diff --git a/hcloud/hcloud.go b/hcloud/hcloud.go
index f850a35..c7bed50 100644
--- a/hcloud/hcloud.go
+++ b/hcloud/hcloud.go
@@ -2,4 +2,4 @@
package hcloud
// Version is the library's version following Semantic Versioning.
-const Version = "1.35.2"
+const Version = "1.39.0" // x-release-please-version
diff --git a/hcloud/helper.go b/hcloud/helper.go
index e8e2642..1965609 100644
--- a/hcloud/helper.go
+++ b/hcloud/helper.go
@@ -2,17 +2,27 @@ package hcloud
import "time"
+// Ptr returns a pointer to p.
+func Ptr[T any](p T) *T {
+ return &p
+}
+
// String returns a pointer to the passed string s.
-func String(s string) *string { return &s }
+//
+// Deprecated: Use [Ptr] instead.
+func String(s string) *string { return Ptr(s) }
// Int returns a pointer to the passed integer i.
-func Int(i int) *int { return &i }
+//
+// Deprecated: Use [Ptr] instead.
+func Int(i int) *int { return Ptr(i) }
// Bool returns a pointer to the passed bool b.
-func Bool(b bool) *bool { return &b }
+//
+// Deprecated: Use [Ptr] instead.
+func Bool(b bool) *bool { return Ptr(b) }
// Duration returns a pointer to the passed time.Duration d.
-func Duration(d time.Duration) *time.Duration { return &d }
-
-func intSlice(is []int) *[]int { return &is }
-func stringSlice(ss []string) *[]string { return &ss }
+//
+// Deprecated: Use [Ptr] instead.
+func Duration(d time.Duration) *time.Duration { return Ptr(d) }
diff --git a/hcloud/image.go b/hcloud/image.go
index 0867aac..6a71898 100644
--- a/hcloud/image.go
+++ b/hcloud/image.go
@@ -222,7 +222,7 @@ func (c *ImageClient) Update(ctx context.Context, image *Image, opts ImageUpdate
Description: opts.Description,
}
if opts.Type != "" {
- reqBody.Type = String(string(opts.Type))
+ reqBody.Type = Ptr(string(opts.Type))
}
if opts.Labels != nil {
reqBody.Labels = &opts.Labels
diff --git a/hcloud/image_test.go b/hcloud/image_test.go
index 6a339c0..28fd0cd 100644
--- a/hcloud/image_test.go
+++ b/hcloud/image_test.go
@@ -338,7 +338,7 @@ func TestImageClientUpdate(t *testing.T) {
})
opts := ImageUpdateOpts{
- Description: String("test"),
+ Description: Ptr("test"),
Type: ImageTypeSnapshot,
}
updatedImage, _, err := env.Client.Image.Update(ctx, image, opts)
@@ -417,7 +417,7 @@ func TestImageClientChangeProtection(t *testing.T) {
})
opts := ImageChangeProtectionOpts{
- Delete: Bool(true),
+ Delete: Ptr(true),
}
action, _, err := env.Client.Image.ChangeProtection(ctx, image, opts)
if err != nil {
diff --git a/hcloud/internal/instrumentation/metrics.go b/hcloud/internal/instrumentation/metrics.go
index d8e9a2e..69a7165 100644
--- a/hcloud/internal/instrumentation/metrics.go
+++ b/hcloud/internal/instrumentation/metrics.go
@@ -16,7 +16,7 @@ type Instrumenter struct {
instrumentationRegistry *prometheus.Registry
}
-// New creates a new Instrumenter. The subsystemIdentifier will be used as part of the metric names (e.g. hcloud_<identifier>_requests_total)
+// New creates a new Instrumenter. The subsystemIdentifier will be used as part of the metric names (e.g. hcloud_<identifier>_requests_total).
func New(subsystemIdentifier string, instrumentationRegistry *prometheus.Registry) *Instrumenter {
return &Instrumenter{subsystemIdentifier: subsystemIdentifier, instrumentationRegistry: instrumentationRegistry}
}
@@ -58,8 +58,10 @@ func (i *Instrumenter) InstrumentedRoundTripper() http.RoundTripper {
// instrumentRoundTripperEndpoint implements a hcloud specific round tripper to count requests per API endpoint
// numeric IDs are removed from the URI Path.
+//
// Sample:
-// /volumes/1234/actions/attach --> /volumes/actions/attach
+//
+// /volumes/1234/actions/attach --> /volumes/actions/attach
func (i *Instrumenter) instrumentRoundTripperEndpoint(counter *prometheus.CounterVec, next http.RoundTripper) promhttp.RoundTripperFunc {
return func(r *http.Request) (*http.Response, error) {
resp, err := next.RoundTrip(r)
@@ -67,6 +69,7 @@ func (i *Instrumenter) instrumentRoundTripperEndpoint(counter *prometheus.Counte
statusCode := strconv.Itoa(resp.StatusCode)
counter.WithLabelValues(statusCode, strings.ToLower(resp.Request.Method), preparePathForLabel(resp.Request.URL.Path)).Inc()
}
+
return resp, err
}
}
diff --git a/hcloud/iso.go b/hcloud/iso.go
index 3ec4a3d..ed2825b 100644
--- a/hcloud/iso.go
+++ b/hcloud/iso.go
@@ -19,7 +19,7 @@ type ISO struct {
Deprecated time.Time
}
-// IsDeprecated returns true if the ISO is deprecated
+// IsDeprecated returns true if the ISO is deprecated.
func (iso *ISO) IsDeprecated() bool {
return !iso.Deprecated.IsZero()
}
diff --git a/hcloud/load_balancer.go b/hcloud/load_balancer.go
index 96aeaf4..81e2e03 100644
--- a/hcloud/load_balancer.go
+++ b/hcloud/load_balancer.go
@@ -491,7 +491,6 @@ type LoadBalancerCreateResult struct {
func (c *LoadBalancerClient) Create(ctx context.Context, opts LoadBalancerCreateOpts) (LoadBalancerCreateResult, *Response, error) {
reqBody := loadBalancerCreateOptsToSchema(opts)
reqBodyData, err := json.Marshal(reqBody)
-
if err != nil {
return LoadBalancerCreateResult{}, nil, err
}
@@ -865,7 +864,7 @@ func (c *LoadBalancerClient) AttachToNetwork(ctx context.Context, loadBalancer *
Network: opts.Network.ID,
}
if opts.IP != nil {
- reqBody.IP = String(opts.IP.String())
+ reqBody.IP = Ptr(opts.IP.String())
}
reqBodyData, err := json.Marshal(reqBody)
if err != nil {
diff --git a/hcloud/load_balancer_test.go b/hcloud/load_balancer_test.go
index e414831..7d78341 100644
--- a/hcloud/load_balancer_test.go
+++ b/hcloud/load_balancer_test.go
@@ -179,7 +179,7 @@ func TestLoadBalancerCreate(t *testing.T) {
Algorithm: &schema.LoadBalancerCreateRequestAlgorithm{
Type: "round_robin",
},
- Location: String("fsn1"),
+ Location: Ptr("fsn1"),
}
if !cmp.Equal(expectedReqBody, reqBody) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
@@ -246,7 +246,7 @@ func TestLoadBalancerClientUpdate(t *testing.T) {
t.Fatal(err)
}
expectedReqBody := schema.LoadBalancerUpdateRequest{
- Name: String("test"),
+ Name: Ptr("test"),
}
if !cmp.Equal(expectedReqBody, reqBody) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
@@ -289,7 +289,7 @@ func TestLoadBalancerClientChangeProtection(t *testing.T) {
t.Fatal(err)
}
expectedReqBody := schema.LoadBalancerActionChangeProtectionRequest{
- Delete: Bool(true),
+ Delete: Ptr(true),
}
if !cmp.Equal(expectedReqBody, reqBody) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
@@ -308,7 +308,7 @@ func TestLoadBalancerClientChangeProtection(t *testing.T) {
)
opts := LoadBalancerChangeProtectionOpts{
- Delete: Bool(true),
+ Delete: Ptr(true),
}
action, _, err := env.Client.LoadBalancer.ChangeProtection(ctx, loadBalancer, opts)
if err != nil {
@@ -336,7 +336,7 @@ func TestLoadBalancerClientAddServerTarget(t *testing.T) {
Server: &schema.LoadBalancerActionAddTargetRequestServer{
ID: 1,
},
- UsePrivateIP: Bool(true),
+ UsePrivateIP: Ptr(true),
}
if !cmp.Equal(expectedReqBody, reqBody) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
@@ -357,7 +357,7 @@ func TestLoadBalancerClientAddServerTarget(t *testing.T) {
opts := LoadBalancerAddServerTargetOpts{
Server: server,
- UsePrivateIP: Bool(true),
+ UsePrivateIP: Ptr(true),
}
action, _, err := env.Client.LoadBalancer.AddServerTarget(ctx, loadBalancer, opts)
if err != nil {
@@ -426,23 +426,23 @@ func TestLoadBalancerAddService(t *testing.T) {
}
expectedReqBody := schema.LoadBalancerActionAddServiceRequest{
Protocol: string(LoadBalancerServiceProtocolHTTP),
- ListenPort: Int(4711),
- DestinationPort: Int(80),
+ ListenPort: Ptr(4711),
+ DestinationPort: Ptr(80),
HTTP: &schema.LoadBalancerActionAddServiceRequestHTTP{
- CookieName: String("HCLBSTICKY"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(false),
- StickySessions: Bool(true),
+ CookieName: Ptr("HCLBSTICKY"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(false),
+ StickySessions: Ptr(true),
},
HealthCheck: &schema.LoadBalancerActionAddServiceRequestHealthCheck{
Protocol: "http",
- Port: Int(4711),
- Interval: Int(15),
- Timeout: Int(10),
- Retries: Int(3),
+ Port: Ptr(4711),
+ Interval: Ptr(15),
+ Timeout: Ptr(10),
+ Retries: Ptr(3),
HTTP: &schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/"),
},
},
}
@@ -464,23 +464,23 @@ func TestLoadBalancerAddService(t *testing.T) {
opts := LoadBalancerAddServiceOpts{
Protocol: LoadBalancerServiceProtocolHTTP,
- ListenPort: Int(4711),
- DestinationPort: Int(80),
+ ListenPort: Ptr(4711),
+ DestinationPort: Ptr(80),
HTTP: &LoadBalancerAddServiceOptsHTTP{
- CookieName: String("HCLBSTICKY"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(false),
- StickySessions: Bool(true),
+ CookieName: Ptr("HCLBSTICKY"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(false),
+ StickySessions: Ptr(true),
},
HealthCheck: &LoadBalancerAddServiceOptsHealthCheck{
Protocol: "http",
- Port: Int(4711),
- Interval: Duration(15 * time.Second),
- Timeout: Duration(10 * time.Second),
- Retries: Int(3),
+ Port: Ptr(4711),
+ Interval: Ptr(15 * time.Second),
+ Timeout: Ptr(10 * time.Second),
+ Retries: Ptr(3),
HTTP: &LoadBalancerAddServiceOptsHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/"),
},
},
}
@@ -506,24 +506,24 @@ func TestLoadBalancerUpdateService(t *testing.T) {
t.Fatal(err)
}
expectedReqBody := schema.LoadBalancerActionUpdateServiceRequest{
- Protocol: String(string(LoadBalancerServiceProtocolHTTP)),
+ Protocol: Ptr(string(LoadBalancerServiceProtocolHTTP)),
ListenPort: 4711,
- DestinationPort: Int(80),
+ DestinationPort: Ptr(80),
HTTP: &schema.LoadBalancerActionUpdateServiceRequestHTTP{
- CookieName: String("HCLBSTICKY"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(false),
- StickySessions: Bool(true),
+ CookieName: Ptr("HCLBSTICKY"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(false),
+ StickySessions: Ptr(true),
},
HealthCheck: &schema.LoadBalancerActionUpdateServiceRequestHealthCheck{
- Protocol: String(string(LoadBalancerServiceProtocolHTTP)),
- Port: Int(4711),
- Interval: Int(15),
- Timeout: Int(10),
- Retries: Int(3),
+ Protocol: Ptr(string(LoadBalancerServiceProtocolHTTP)),
+ Port: Ptr(4711),
+ Interval: Ptr(15),
+ Timeout: Ptr(10),
+ Retries: Ptr(3),
HTTP: &schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/"),
},
},
}
@@ -545,22 +545,22 @@ func TestLoadBalancerUpdateService(t *testing.T) {
opts := LoadBalancerUpdateServiceOpts{
Protocol: LoadBalancerServiceProtocolHTTP,
- DestinationPort: Int(80),
+ DestinationPort: Ptr(80),
HTTP: &LoadBalancerUpdateServiceOptsHTTP{
- CookieName: String("HCLBSTICKY"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(false),
- StickySessions: Bool(true),
+ CookieName: Ptr("HCLBSTICKY"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(false),
+ StickySessions: Ptr(true),
},
HealthCheck: &LoadBalancerUpdateServiceOptsHealthCheck{
Protocol: LoadBalancerServiceProtocolHTTP,
- Port: Int(4711),
- Interval: Duration(15 * time.Second),
- Timeout: Duration(10 * time.Second),
- Retries: Int(3),
+ Port: Ptr(4711),
+ Interval: Ptr(15 * time.Second),
+ Timeout: Ptr(10 * time.Second),
+ Retries: Ptr(3),
HTTP: &LoadBalancerUpdateServiceOptsHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/"),
},
},
}
@@ -670,7 +670,7 @@ func TestLoadBalancerClientAttachToNetwork(t *testing.T) {
}
expectedReqBody := schema.LoadBalancerActionAttachToNetworkRequest{
Network: 1,
- IP: String("10.0.1.1"),
+ IP: Ptr("10.0.1.1"),
}
if !cmp.Equal(expectedReqBody, reqBody) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
@@ -898,7 +898,7 @@ func TestLoadBalancerClientAddLabelSelectorTarget(t *testing.T) {
ctx := context.Background()
action, _, err := env.Client.LoadBalancer.AddLabelSelectorTarget(ctx, &LoadBalancer{ID: 1}, LoadBalancerAddLabelSelectorTargetOpts{
Selector: "key=value",
- UsePrivateIP: Bool(false),
+ UsePrivateIP: Ptr(false),
})
if err != nil {
t.Fatal(err)
diff --git a/hcloud/metadata/client.go b/hcloud/metadata/client.go
index 7bfa18e..4c173d7 100644
--- a/hcloud/metadata/client.go
+++ b/hcloud/metadata/client.go
@@ -8,8 +8,9 @@ import (
"strconv"
"strings"
- "github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation"
"github.com/prometheus/client_golang/prometheus"
+
+ "github.com/hetznercloud/hcloud-go/hcloud/internal/instrumentation"
)
const Endpoint = "http://169.254.169.254/hetzner/v1/metadata"
@@ -85,7 +86,7 @@ func (c *Client) get(path string) (string, error) {
}
// IsHcloudServer checks if the currently called server is a hcloud server by calling a metadata endpoint
-// if the endpoint answers with a non-empty value this method returns true, otherwise false
+// if the endpoint answers with a non-empty value this method returns true, otherwise false.
func (c *Client) IsHcloudServer() bool {
hostname, err := c.Hostname()
if err != nil {
@@ -97,12 +98,12 @@ func (c *Client) IsHcloudServer() bool {
return false
}
-// Hostname returns the hostname of the server that did the request to the Metadata server
+// Hostname returns the hostname of the server that did the request to the Metadata server.
func (c *Client) Hostname() (string, error) {
return c.get("/hostname")
}
-// InstanceID returns the ID of the server that did the request to the Metadata server
+// InstanceID returns the ID of the server that did the request to the Metadata server.
func (c *Client) InstanceID() (int, error) {
resp, err := c.get("/instance-id")
if err != nil {
@@ -111,7 +112,7 @@ func (c *Client) InstanceID() (int, error) {
return strconv.Atoi(resp)
}
-// PublicIPv4 returns the Public IPv4 of the server that did the request to the Metadata server
+// PublicIPv4 returns the Public IPv4 of the server that did the request to the Metadata server.
func (c *Client) PublicIPv4() (net.IP, error) {
resp, err := c.get("/public-ipv4")
if err != nil {
@@ -120,18 +121,18 @@ func (c *Client) PublicIPv4() (net.IP, error) {
return net.ParseIP(resp), nil
}
-// Region returns the Network Zone of the server that did the request to the Metadata server
+// Region returns the Network Zone of the server that did the request to the Metadata server.
func (c *Client) Region() (string, error) {
return c.get("/region")
}
-// AvailabilityZone returns the datacenter of the server that did the request to the Metadata server
+// AvailabilityZone returns the datacenter of the server that did the request to the Metadata server.
func (c *Client) AvailabilityZone() (string, error) {
return c.get("/availability-zone")
}
-// PrivateNetworks returns details about the private networks the server is attached to
-// Returns YAML (unparsed)
+// PrivateNetworks returns details about the private networks the server is attached to.
+// Returns YAML (unparsed).
func (c *Client) PrivateNetworks() (string, error) {
return c.get("/private-networks")
}
diff --git a/hcloud/network.go b/hcloud/network.go
index e3bf6de..5a19681 100644
--- a/hcloud/network.go
+++ b/hcloud/network.go
@@ -21,6 +21,7 @@ type NetworkZone string
const (
NetworkZoneEUCentral NetworkZone = "eu-central"
NetworkZoneUSEast NetworkZone = "us-east"
+ NetworkZoneUSWest NetworkZone = "us-west"
)
// NetworkSubnetType specifies a type of a subnet.
diff --git a/hcloud/network_test.go b/hcloud/network_test.go
index 5b0855b..d5f5d00 100644
--- a/hcloud/network_test.go
+++ b/hcloud/network_test.go
@@ -622,7 +622,7 @@ func TestNetworkClientChangeProtection(t *testing.T) {
})
opts := NetworkChangeProtectionOpts{
- Delete: Bool(true),
+ Delete: Ptr(true),
}
action, _, err := env.Client.Network.ChangeProtection(ctx, network, opts)
if err != nil {
diff --git a/hcloud/placement_group.go b/hcloud/placement_group.go
index 5056a11..07fedad 100644
--- a/hcloud/placement_group.go
+++ b/hcloud/placement_group.go
@@ -23,11 +23,11 @@ type PlacementGroup struct {
Type PlacementGroupType
}
-// PlacementGroupType specifies the type of a Placement Group
+// PlacementGroupType specifies the type of a Placement Group.
type PlacementGroupType string
const (
- // PlacementGroupTypeSpread spreads all servers in the group on different vhosts
+ // PlacementGroupTypeSpread spreads all servers in the group on different vhosts.
PlacementGroupTypeSpread PlacementGroupType = "spread"
)
@@ -158,7 +158,7 @@ type PlacementGroupCreateOpts struct {
Type PlacementGroupType
}
-// Validate checks if options are valid
+// Validate checks if options are valid.
func (o PlacementGroupCreateOpts) Validate() error {
if o.Name == "" {
return errors.New("missing name")
@@ -172,7 +172,7 @@ type PlacementGroupCreateResult struct {
Action *Action
}
-// Create creates a new PlacementGroup
+// Create creates a new PlacementGroup.
func (c *PlacementGroupClient) Create(ctx context.Context, opts PlacementGroupCreateOpts) (PlacementGroupCreateResult, *Response, error) {
if err := opts.Validate(); err != nil {
return PlacementGroupCreateResult{}, nil, err
diff --git a/hcloud/placement_group_test.go b/hcloud/placement_group_test.go
index 334f591..fd2caed 100644
--- a/hcloud/placement_group_test.go
+++ b/hcloud/placement_group_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
+
"github.com/hetznercloud/hcloud-go/hcloud/schema"
)
diff --git a/hcloud/pricing.go b/hcloud/pricing.go
index 67be21f..836f391 100644
--- a/hcloud/pricing.go
+++ b/hcloud/pricing.go
@@ -56,12 +56,13 @@ type FloatingIPTypePricing struct {
// PrimaryIPTypePricing defines the schema of pricing information for a primary IP
// type at a datacenter.
type PrimaryIPTypePricing struct {
- Datacenter string
+ Datacenter string // Deprecated: the API does not return pricing for the individual DCs anymore
+ Location string
Hourly PrimaryIPPrice
Monthly PrimaryIPPrice
}
-// PrimaryIPTypePricing provides pricing information for PrimaryIPs
+// PrimaryIPTypePricing provides pricing information for PrimaryIPs.
type PrimaryIPPricing struct {
Type string
Pricings []PrimaryIPTypePricing
diff --git a/hcloud/primary_ip.go b/hcloud/primary_ip.go
index c534c89..e328b9b 100644
--- a/hcloud/primary_ip.go
+++ b/hcloud/primary_ip.go
@@ -13,7 +13,7 @@ import (
"github.com/hetznercloud/hcloud-go/hcloud/schema"
)
-// PrimaryIP defines a Primary IP
+// PrimaryIP defines a Primary IP.
type PrimaryIP struct {
ID int
IP net.IP
@@ -90,12 +90,6 @@ type PrimaryIPUpdateOpts struct {
Name string `json:"name,omitempty"`
}
-// PrimaryIPUpdateResult defines the response
-// when updating a Primary IP.
-type PrimaryIPUpdateResult struct {
- PrimaryIP PrimaryIP `json:"primary_ip"`
-}
-
// PrimaryIPAssignOpts defines the request to
// assign a Primary IP to an assignee (usually a server).
type PrimaryIPAssignOpts struct {
@@ -111,7 +105,7 @@ type PrimaryIPAssignResult struct {
}
// PrimaryIPChangeDNSPtrOpts defines the request to
-// change a DNS PTR entry from a Primary IP
+// change a DNS PTR entry from a Primary IP.
type PrimaryIPChangeDNSPtrOpts struct {
ID int
DNSPtr string `json:"dns_ptr"`
@@ -125,19 +119,19 @@ type PrimaryIPChangeDNSPtrResult struct {
}
// PrimaryIPChangeProtectionOpts defines the request to
-// change protection configuration of a Primary IP
+// change protection configuration of a Primary IP.
type PrimaryIPChangeProtectionOpts struct {
ID int
Delete bool `json:"delete"`
}
// PrimaryIPChangeProtectionResult defines the response
-// when changing a protection of a PrimaryIP
+// when changing a protection of a PrimaryIP.
type PrimaryIPChangeProtectionResult struct {
Action schema.Action `json:"action"`
}
-// PrimaryIPClient is a client for the Primary IP API
+// PrimaryIPClient is a client for the Primary IP API.
type PrimaryIPClient struct {
client *Client
}
@@ -240,10 +234,12 @@ func (c *PrimaryIPClient) List(ctx context.Context, opts PrimaryIPListOpts) ([]*
// All returns all Primary IPs.
func (c *PrimaryIPClient) All(ctx context.Context) ([]*PrimaryIP, error) {
- allPrimaryIPs := []*PrimaryIP{}
+ return c.AllWithOpts(ctx, PrimaryIPListOpts{ListOpts: ListOpts{PerPage: 50}})
+}
- opts := PrimaryIPListOpts{}
- opts.PerPage = 50
+// AllWithOpts returns all Primary IPs for the given options.
+func (c *PrimaryIPClient) AllWithOpts(ctx context.Context, opts PrimaryIPListOpts) ([]*PrimaryIP, error) {
+ var allPrimaryIPs []*PrimaryIP
err := c.client.all(func(page int) (*Response, error) {
opts.Page = page
@@ -311,15 +307,15 @@ func (c *PrimaryIPClient) Update(ctx context.Context, primaryIP *PrimaryIP, reqB
return nil, nil, err
}
- respBody := PrimaryIPUpdateResult{}
+ var respBody schema.PrimaryIPUpdateResult
resp, err := c.client.Do(req, &respBody)
if err != nil {
return nil, resp, err
}
- return &respBody.PrimaryIP, resp, nil
+ return PrimaryIPFromSchema(respBody.PrimaryIP), resp, nil
}
-// Assign a Primary IP to a resource
+// 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 {
@@ -340,7 +336,7 @@ func (c *PrimaryIPClient) Assign(ctx context.Context, opts PrimaryIPAssignOpts)
return ActionFromSchema(respBody.Action), resp, nil
}
-// Unassign a Primary IP from a resource
+// 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{}))
@@ -356,7 +352,7 @@ func (c *PrimaryIPClient) Unassign(ctx context.Context, id int) (*Action, *Respo
return ActionFromSchema(respBody.Action), resp, nil
}
-// ChangeDNSPtr Change the reverse DNS from a Primary IP
+// 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 {
diff --git a/hcloud/primary_ip_test.go b/hcloud/primary_ip_test.go
index 6c517ee..d368b71 100644
--- a/hcloud/primary_ip_test.go
+++ b/hcloud/primary_ip_test.go
@@ -3,12 +3,14 @@ package hcloud
import (
"context"
"encoding/json"
+ "net"
"net/http"
"testing"
"github.com/google/go-cmp/cmp"
- "github.com/hetznercloud/hcloud-go/hcloud/schema"
"github.com/stretchr/testify/assert"
+
+ "github.com/hetznercloud/hcloud-go/hcloud/schema"
)
func TestPrimaryIPClient(t *testing.T) {
@@ -333,8 +335,8 @@ func TestPrimaryIPClient(t *testing.T) {
t.Log(cmp.Diff(expectedReqBody, reqBody))
t.Error("unexpected request body")
}
- json.NewEncoder(w).Encode(PrimaryIPUpdateResult{
- PrimaryIP: PrimaryIP{ID: 1},
+ json.NewEncoder(w).Encode(schema.PrimaryIPUpdateResult{
+ PrimaryIP: schema.PrimaryIP{ID: 1, IP: "2001:db8::/64"},
})
})
@@ -347,11 +349,14 @@ func TestPrimaryIPClient(t *testing.T) {
Labels: &labels,
}
- primaryIP := PrimaryIP{ID: 1}
+ primaryIP := PrimaryIP{ID: 1, IP: net.ParseIP("2001:db8::")}
result, resp, err := env.Client.PrimaryIP.Update(ctx, &primaryIP, opts)
assert.NoError(t, err)
assert.NotNil(t, resp, "no response returned")
- assert.Equal(t, *result, primaryIP, "no primary IP returned")
+ if result.ID != 1 {
+ t.Errorf("unexpected Primary IP ID: %v", result.ID)
+ }
+ assert.Equal(t, primaryIP.IP, result.IP, "parsed the wrong IP")
})
t.Run("Assign", func(t *testing.T) {
env := newTestEnv()
diff --git a/hcloud/rdns.go b/hcloud/rdns.go
index 70d31f9..891ea2b 100644
--- a/hcloud/rdns.go
+++ b/hcloud/rdns.go
@@ -7,7 +7,7 @@ import (
)
// RDNSSupporter defines functions to change and lookup reverse dns entries.
-// currently implemented by Server, FloatingIP and LoadBalancer
+// currently implemented by Server, FloatingIP and LoadBalancer.
type RDNSSupporter 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.
diff --git a/hcloud/schema.go b/hcloud/schema.go
index 633a568..091426b 100644
--- a/hcloud/schema.go
+++ b/hcloud/schema.go
@@ -721,7 +721,7 @@ func PricingFromSchema(s schema.Pricing) Pricing {
var pricings []PrimaryIPTypePricing
for _, price := range primaryIPType.Prices {
p := PrimaryIPTypePricing{
- Datacenter: price.Datacenter,
+ Location: price.Location,
Monthly: PrimaryIPPrice{
Net: price.PriceMonthly.Net,
Gross: price.PriceMonthly.Gross,
@@ -881,19 +881,19 @@ func loadBalancerCreateOptsToSchema(opts LoadBalancerCreateOpts) schema.LoadBala
}
if opts.Location != nil {
if opts.Location.ID != 0 {
- req.Location = String(strconv.Itoa(opts.Location.ID))
+ req.Location = Ptr(strconv.Itoa(opts.Location.ID))
} else {
- req.Location = String(opts.Location.Name)
+ req.Location = Ptr(opts.Location.Name)
}
}
if opts.NetworkZone != "" {
- req.NetworkZone = String(string(opts.NetworkZone))
+ req.NetworkZone = Ptr(string(opts.NetworkZone))
}
if opts.Labels != nil {
req.Labels = &opts.Labels
}
if opts.Network != nil {
- req.Network = Int(opts.Network.ID)
+ req.Network = Ptr(opts.Network.ID)
}
for _, target := range opts.Targets {
schemaTarget := schema.LoadBalancerCreateRequestTarget{
@@ -927,7 +927,7 @@ func loadBalancerCreateOptsToSchema(opts LoadBalancerCreateOpts) schema.LoadBala
}
if service.HTTP.CookieLifetime != nil {
if sec := service.HTTP.CookieLifetime.Seconds(); sec != 0 {
- schemaService.HTTP.CookieLifetime = Int(int(sec))
+ schemaService.HTTP.CookieLifetime = Ptr(int(sec))
}
}
if service.HTTP.Certificates != nil {
@@ -945,10 +945,10 @@ func loadBalancerCreateOptsToSchema(opts LoadBalancerCreateOpts) schema.LoadBala
Retries: service.HealthCheck.Retries,
}
if service.HealthCheck.Interval != nil {
- schemaHealthCheck.Interval = Int(int(service.HealthCheck.Interval.Seconds()))
+ schemaHealthCheck.Interval = Ptr(int(service.HealthCheck.Interval.Seconds()))
}
if service.HealthCheck.Timeout != nil {
- schemaHealthCheck.Timeout = Int(int(service.HealthCheck.Timeout.Seconds()))
+ schemaHealthCheck.Timeout = Ptr(int(service.HealthCheck.Timeout.Seconds()))
}
if service.HealthCheck.HTTP != nil {
schemaHealthCheckHTTP := &schema.LoadBalancerCreateRequestServiceHealthCheckHTTP{
@@ -983,7 +983,7 @@ func loadBalancerAddServiceOptsToSchema(opts LoadBalancerAddServiceOpts) schema.
StickySessions: opts.HTTP.StickySessions,
}
if opts.HTTP.CookieLifetime != nil {
- req.HTTP.CookieLifetime = Int(int(opts.HTTP.CookieLifetime.Seconds()))
+ req.HTTP.CookieLifetime = Ptr(int(opts.HTTP.CookieLifetime.Seconds()))
}
if opts.HTTP.Certificates != nil {
certificates := []int{}
@@ -1000,10 +1000,10 @@ func loadBalancerAddServiceOptsToSchema(opts LoadBalancerAddServiceOpts) schema.
Retries: opts.HealthCheck.Retries,
}
if opts.HealthCheck.Interval != nil {
- req.HealthCheck.Interval = Int(int(opts.HealthCheck.Interval.Seconds()))
+ req.HealthCheck.Interval = Ptr(int(opts.HealthCheck.Interval.Seconds()))
}
if opts.HealthCheck.Timeout != nil {
- req.HealthCheck.Timeout = Int(int(opts.HealthCheck.Timeout.Seconds()))
+ req.HealthCheck.Timeout = Ptr(int(opts.HealthCheck.Timeout.Seconds()))
}
if opts.HealthCheck.HTTP != nil {
req.HealthCheck.HTTP = &schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP{
@@ -1026,7 +1026,7 @@ func loadBalancerUpdateServiceOptsToSchema(opts LoadBalancerUpdateServiceOpts) s
Proxyprotocol: opts.Proxyprotocol,
}
if opts.Protocol != "" {
- req.Protocol = String(string(opts.Protocol))
+ req.Protocol = Ptr(string(opts.Protocol))
}
if opts.HTTP != nil {
req.HTTP = &schema.LoadBalancerActionUpdateServiceRequestHTTP{
@@ -1035,7 +1035,7 @@ func loadBalancerUpdateServiceOptsToSchema(opts LoadBalancerUpdateServiceOpts) s
StickySessions: opts.HTTP.StickySessions,
}
if opts.HTTP.CookieLifetime != nil {
- req.HTTP.CookieLifetime = Int(int(opts.HTTP.CookieLifetime.Seconds()))
+ req.HTTP.CookieLifetime = Ptr(int(opts.HTTP.CookieLifetime.Seconds()))
}
if opts.HTTP.Certificates != nil {
certificates := []int{}
@@ -1051,13 +1051,13 @@ func loadBalancerUpdateServiceOptsToSchema(opts LoadBalancerUpdateServiceOpts) s
Retries: opts.HealthCheck.Retries,
}
if opts.HealthCheck.Interval != nil {
- req.HealthCheck.Interval = Int(int(opts.HealthCheck.Interval.Seconds()))
+ req.HealthCheck.Interval = Ptr(int(opts.HealthCheck.Interval.Seconds()))
}
if opts.HealthCheck.Timeout != nil {
- req.HealthCheck.Timeout = Int(int(opts.HealthCheck.Timeout.Seconds()))
+ req.HealthCheck.Timeout = Ptr(int(opts.HealthCheck.Timeout.Seconds()))
}
if opts.HealthCheck.Protocol != "" {
- req.HealthCheck.Protocol = String(string(opts.HealthCheck.Protocol))
+ req.HealthCheck.Protocol = Ptr(string(opts.HealthCheck.Protocol))
}
if opts.HealthCheck.HTTP != nil {
req.HealthCheck.HTTP = &schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP{
diff --git a/hcloud/schema/pricing.go b/hcloud/schema/pricing.go
index b97a2f8..0c06c73 100644
--- a/hcloud/schema/pricing.go
+++ b/hcloud/schema/pricing.go
@@ -94,15 +94,16 @@ type PricingGetResponse struct {
Pricing Pricing `json:"pricing"`
}
-// PricingPrimaryIPTypePrice defines the schema of pricing information for a primary IP
+// PricingPrimaryIPTypePrice defines the schema of pricing information for a primary IP.
// type at a datacenter.
type PricingPrimaryIPTypePrice struct {
- Datacenter string `json:"datacenter"`
+ Datacenter string `json:"datacenter"` // Deprecated: the API does not return pricing for the individual DCs anymore
+ Location string `json:"location"`
PriceHourly Price `json:"price_hourly"`
PriceMonthly Price `json:"price_monthly"`
}
-// PricingPrimaryIP define the schema of pricing information for a primary IP at a datacenter
+// PricingPrimaryIP define the schema of pricing information for a primary IP at a datacenter.
type PricingPrimaryIP struct {
Type string `json:"type"`
Prices []PricingPrimaryIPTypePrice `json:"prices"`
diff --git a/hcloud/schema/primary_ip.go b/hcloud/schema/primary_ip.go
index b21e28b..d232a73 100644
--- a/hcloud/schema/primary_ip.go
+++ b/hcloud/schema/primary_ip.go
@@ -2,7 +2,7 @@ package schema
import "time"
-// PrimaryIP defines a Primary IP
+// PrimaryIP defines a Primary IP.
type PrimaryIP struct {
ID int `json:"id"`
IP string `json:"ip"`
@@ -47,3 +47,9 @@ type PrimaryIPGetResult struct {
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"`
+}
diff --git a/hcloud/schema/server.go b/hcloud/schema/server.go
index 616b2eb..654ccfc 100644
--- a/hcloud/schema/server.go
+++ b/hcloud/schema/server.go
@@ -136,6 +136,12 @@ type ServerCreateResponse struct {
NextActions []Action `json:"next_actions"`
}
+// ServerDeleteResponse defines the schema of the response when
+// deleting a server.
+type ServerDeleteResponse struct {
+ Action Action `json:"action"`
+}
+
// ServerUpdateRequest defines the schema of the request to update a server.
type ServerUpdateRequest struct {
Name string `json:"name,omitempty"`
diff --git a/hcloud/schema_test.go b/hcloud/schema_test.go
index 9301d78..fd0a364 100644
--- a/hcloud/schema_test.go
+++ b/hcloud/schema_test.go
@@ -2044,7 +2044,7 @@ func TestPricingFromSchema(t *testing.T) {
{
"prices": [
{
- "datacenter": "fsn1-dc8",
+ "location": "fsn1",
"price_hourly": {
"gross": "1.1900000000000000",
"net": "1.0000000000"
@@ -2185,8 +2185,8 @@ func TestPricingFromSchema(t *testing.T) {
if len(ip.Pricings) != 1 {
t.Errorf("unexpected number of prices: %d", len(ip.Pricings))
} else {
- if ip.Pricings[0].Datacenter != "fsn1-dc8" {
- t.Errorf("unexpected Datacenter: %v", ip.Pricings[0].Datacenter)
+ if ip.Pricings[0].Location != "fsn1" {
+ t.Errorf("unexpected Location: %v", ip.Pricings[0].Location)
}
if ip.Pricings[0].Monthly.Net != "1.0000000000" {
t.Errorf("unexpected Monthly.Net: %v", ip.Pricings[0].Monthly.Net)
@@ -2346,7 +2346,7 @@ func TestLoadBalancerCreateOptsToSchema(t *testing.T) {
Algorithm: &schema.LoadBalancerCreateRequestAlgorithm{
Type: string(LoadBalancerAlgorithmTypeRoundRobin),
},
- NetworkZone: String(string(NetworkZoneEUCentral)),
+ NetworkZone: Ptr(string(NetworkZoneEUCentral)),
},
},
"all set": {
@@ -2356,32 +2356,32 @@ func TestLoadBalancerCreateOptsToSchema(t *testing.T) {
Algorithm: &LoadBalancerAlgorithm{Type: LoadBalancerAlgorithmTypeRoundRobin},
NetworkZone: NetworkZoneEUCentral,
Labels: map[string]string{"foo": "bar"},
- PublicInterface: Bool(true),
+ PublicInterface: Ptr(true),
Network: &Network{ID: 3},
Services: []LoadBalancerCreateOptsService{
{
Protocol: LoadBalancerServiceProtocolHTTP,
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &LoadBalancerCreateOptsServiceHTTP{
- CookieName: String("keks"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
Certificates: []*Certificate{{ID: 1}, {ID: 2}},
},
HealthCheck: &LoadBalancerCreateOptsServiceHealthCheck{
Protocol: LoadBalancerServiceProtocolHTTP,
- Port: Int(80),
- Interval: Duration(5 * time.Second),
- Timeout: Duration(1 * time.Second),
- Retries: Int(3),
+ Port: Ptr(80),
+ Interval: Ptr(5 * time.Second),
+ Timeout: Ptr(1 * time.Second),
+ Retries: Ptr(3),
HTTP: &LoadBalancerCreateOptsServiceHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/health"),
- Response: String("ok"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/health"),
+ Response: Ptr("ok"),
StatusCodes: []string{"2??", "3??"},
- TLS: Bool(true),
+ TLS: Ptr(true),
},
},
},
@@ -2405,37 +2405,37 @@ func TestLoadBalancerCreateOptsToSchema(t *testing.T) {
Algorithm: &schema.LoadBalancerCreateRequestAlgorithm{
Type: string(LoadBalancerAlgorithmTypeRoundRobin),
},
- NetworkZone: String(string(NetworkZoneEUCentral)),
+ NetworkZone: Ptr(string(NetworkZoneEUCentral)),
Labels: func() *map[string]string {
labels := map[string]string{"foo": "bar"}
return &labels
}(),
- PublicInterface: Bool(true),
- Network: Int(3),
+ PublicInterface: Ptr(true),
+ Network: Ptr(3),
Services: []schema.LoadBalancerCreateRequestService{
{
Protocol: string(LoadBalancerServiceProtocolHTTP),
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &schema.LoadBalancerCreateRequestServiceHTTP{
- CookieName: String("keks"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
- Certificates: intSlice([]int{1, 2}),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
+ Certificates: Ptr([]int{1, 2}),
},
HealthCheck: &schema.LoadBalancerCreateRequestServiceHealthCheck{
Protocol: string(LoadBalancerServiceProtocolHTTP),
- Port: Int(80),
- Interval: Int(5),
- Timeout: Int(1),
- Retries: Int(3),
+ Port: Ptr(80),
+ Interval: Ptr(5),
+ Timeout: Ptr(1),
+ Retries: Ptr(3),
HTTP: &schema.LoadBalancerCreateRequestServiceHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/health"),
- Response: String("ok"),
- StatusCodes: stringSlice([]string{"2??", "3??"}),
- TLS: Bool(true),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/health"),
+ Response: Ptr("ok"),
+ StatusCodes: Ptr([]string{"2??", "3??"}),
+ TLS: Ptr(true),
},
},
},
@@ -2484,53 +2484,53 @@ func TestLoadBalancerAddServiceOptsToSchema(t *testing.T) {
"all set": {
Opts: LoadBalancerAddServiceOpts{
Protocol: LoadBalancerServiceProtocolHTTP,
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &LoadBalancerAddServiceOptsHTTP{
- CookieName: String("keks"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
Certificates: []*Certificate{{ID: 1}, {ID: 2}},
},
HealthCheck: &LoadBalancerAddServiceOptsHealthCheck{
Protocol: LoadBalancerServiceProtocolHTTP,
- Port: Int(80),
- Interval: Duration(5 * time.Second),
- Timeout: Duration(1 * time.Second),
- Retries: Int(3),
+ Port: Ptr(80),
+ Interval: Ptr(5 * time.Second),
+ Timeout: Ptr(1 * time.Second),
+ Retries: Ptr(3),
HTTP: &LoadBalancerAddServiceOptsHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/health"),
- Response: String("ok"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/health"),
+ Response: Ptr("ok"),
StatusCodes: []string{"2??", "3??"},
- TLS: Bool(true),
+ TLS: Ptr(true),
},
},
},
Request: schema.LoadBalancerActionAddServiceRequest{
Protocol: string(LoadBalancerServiceProtocolHTTP),
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &schema.LoadBalancerActionAddServiceRequestHTTP{
- CookieName: String("keks"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
- Certificates: intSlice([]int{1, 2}),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
+ Certificates: Ptr([]int{1, 2}),
},
HealthCheck: &schema.LoadBalancerActionAddServiceRequestHealthCheck{
Protocol: string(LoadBalancerServiceProtocolHTTP),
- Port: Int(80),
- Interval: Int(5),
- Timeout: Int(1),
- Retries: Int(3),
+ Port: Ptr(80),
+ Interval: Ptr(5),
+ Timeout: Ptr(1),
+ Retries: Ptr(3),
HTTP: &schema.LoadBalancerActionAddServiceRequestHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/health"),
- Response: String("ok"),
- StatusCodes: stringSlice([]string{"2??", "3??"}),
- TLS: Bool(true),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/health"),
+ Response: Ptr("ok"),
+ StatusCodes: Ptr([]string{"2??", "3??"}),
+ TLS: Ptr(true),
},
},
},
@@ -2538,26 +2538,26 @@ func TestLoadBalancerAddServiceOptsToSchema(t *testing.T) {
"no health check": {
Opts: LoadBalancerAddServiceOpts{
Protocol: LoadBalancerServiceProtocolHTTP,
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &LoadBalancerAddServiceOptsHTTP{
- CookieName: String("keks"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
Certificates: []*Certificate{{ID: 1}, {ID: 2}},
},
},
Request: schema.LoadBalancerActionAddServiceRequest{
Protocol: string(LoadBalancerServiceProtocolHTTP),
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &schema.LoadBalancerActionAddServiceRequestHTTP{
- CookieName: String("keks"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
- Certificates: intSlice([]int{1, 2}),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
+ Certificates: Ptr([]int{1, 2}),
},
HealthCheck: nil,
},
@@ -2586,53 +2586,53 @@ func TestLoadBalancerUpdateServiceOptsToSchema(t *testing.T) {
"all set": {
Opts: LoadBalancerUpdateServiceOpts{
Protocol: LoadBalancerServiceProtocolHTTP,
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &LoadBalancerUpdateServiceOptsHTTP{
- CookieName: String("keks"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
Certificates: []*Certificate{{ID: 1}, {ID: 2}},
},
HealthCheck: &LoadBalancerUpdateServiceOptsHealthCheck{
Protocol: LoadBalancerServiceProtocolHTTP,
- Port: Int(80),
- Interval: Duration(5 * time.Second),
- Timeout: Duration(1 * time.Second),
- Retries: Int(3),
+ Port: Ptr(80),
+ Interval: Ptr(5 * time.Second),
+ Timeout: Ptr(1 * time.Second),
+ Retries: Ptr(3),
HTTP: &LoadBalancerUpdateServiceOptsHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/health"),
- Response: String("ok"),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/health"),
+ Response: Ptr("ok"),
StatusCodes: []string{"2??", "3??"},
- TLS: Bool(true),
+ TLS: Ptr(true),
},
},
},
Request: schema.LoadBalancerActionUpdateServiceRequest{
- Protocol: String(string(LoadBalancerServiceProtocolHTTP)),
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ Protocol: Ptr(string(LoadBalancerServiceProtocolHTTP)),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &schema.LoadBalancerActionUpdateServiceRequestHTTP{
- CookieName: String("keks"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
- Certificates: intSlice([]int{1, 2}),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
+ Certificates: Ptr([]int{1, 2}),
},
HealthCheck: &schema.LoadBalancerActionUpdateServiceRequestHealthCheck{
- Protocol: String(string(LoadBalancerServiceProtocolHTTP)),
- Port: Int(80),
- Interval: Int(5),
- Timeout: Int(1),
- Retries: Int(3),
+ Protocol: Ptr(string(LoadBalancerServiceProtocolHTTP)),
+ Port: Ptr(80),
+ Interval: Ptr(5),
+ Timeout: Ptr(1),
+ Retries: Ptr(3),
HTTP: &schema.LoadBalancerActionUpdateServiceRequestHealthCheckHTTP{
- Domain: String("example.com"),
- Path: String("/health"),
- Response: String("ok"),
- StatusCodes: stringSlice([]string{"2??", "3??"}),
- TLS: Bool(true),
+ Domain: Ptr("example.com"),
+ Path: Ptr("/health"),
+ Response: Ptr("ok"),
+ StatusCodes: Ptr([]string{"2??", "3??"}),
+ TLS: Ptr(true),
},
},
},
@@ -2640,26 +2640,26 @@ func TestLoadBalancerUpdateServiceOptsToSchema(t *testing.T) {
"no health check": {
Opts: LoadBalancerUpdateServiceOpts{
Protocol: LoadBalancerServiceProtocolHTTP,
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &LoadBalancerUpdateServiceOptsHTTP{
- CookieName: String("keks"),
- CookieLifetime: Duration(5 * time.Minute),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * time.Minute),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
Certificates: []*Certificate{{ID: 1}, {ID: 2}},
},
},
Request: schema.LoadBalancerActionUpdateServiceRequest{
- Protocol: String(string(LoadBalancerServiceProtocolHTTP)),
- DestinationPort: Int(80),
- Proxyprotocol: Bool(true),
+ Protocol: Ptr(string(LoadBalancerServiceProtocolHTTP)),
+ DestinationPort: Ptr(80),
+ Proxyprotocol: Ptr(true),
HTTP: &schema.LoadBalancerActionUpdateServiceRequestHTTP{
- CookieName: String("keks"),
- CookieLifetime: Int(5 * 60),
- RedirectHTTP: Bool(true),
- StickySessions: Bool(true),
- Certificates: intSlice([]int{1, 2}),
+ CookieName: Ptr("keks"),
+ CookieLifetime: Ptr(5 * 60),
+ RedirectHTTP: Ptr(true),
+ StickySessions: Ptr(true),
+ Certificates: Ptr([]int{1, 2}),
},
HealthCheck: nil,
},
diff --git a/hcloud/server.go b/hcloud/server.go
index 00bcb90..da708a2 100644
--- a/hcloud/server.go
+++ b/hcloud/server.go
@@ -458,13 +458,34 @@ func (c *ServerClient) Create(ctx context.Context, opts ServerCreateOpts) (Serve
return result, resp, nil
}
+// ServerDeleteResult is the result of a delete server call.
+type ServerDeleteResult struct {
+ Action *Action
+}
+
// Delete deletes a server.
+// This method is deprecated, use ServerClient.DeleteWithResult instead.
func (c *ServerClient) Delete(ctx context.Context, server *Server) (*Response, error) {
+ _, resp, err := c.DeleteWithResult(ctx, server)
+ return resp, err
+}
+
+// Delete 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 nil, err
+ return &ServerDeleteResult{}, nil, err
}
- return c.client.Do(req, nil)
+
+ var respBody schema.ServerDeleteResponse
+ resp, err := c.client.Do(req, &respBody)
+ if err != nil {
+ return &ServerDeleteResult{}, resp, err
+ }
+
+ return &ServerDeleteResult{
+ Action: ActionFromSchema(respBody.Action),
+ }, resp, nil
}
// ServerUpdateOpts specifies options for updating a server.
@@ -643,7 +664,7 @@ func (c *ServerClient) CreateImage(ctx context.Context, server *Server, opts *Se
reqBody.Description = opts.Description
}
if opts.Type != "" {
- reqBody.Type = String(string(opts.Type))
+ reqBody.Type = Ptr(string(opts.Type))
}
if opts.Labels != nil {
reqBody.Labels = &opts.Labels
@@ -686,7 +707,7 @@ type ServerEnableRescueResult struct {
// EnableRescue enables rescue mode for a server.
func (c *ServerClient) EnableRescue(ctx context.Context, server *Server, opts ServerEnableRescueOpts) (ServerEnableRescueResult, *Response, error) {
reqBody := schema.ServerActionEnableRescueRequest{
- Type: String(string(opts.Type)),
+ Type: Ptr(string(opts.Type)),
}
for _, sshKey := range opts.SSHKeys {
reqBody.SSHKeys = append(reqBody.SSHKeys, sshKey.ID)
@@ -811,7 +832,7 @@ func (c *ServerClient) DetachISO(ctx context.Context, server *Server) (*Action,
func (c *ServerClient) EnableBackup(ctx context.Context, server *Server, window string) (*Action, *Response, error) {
reqBody := schema.ServerActionEnableBackupRequest{}
if window != "" {
- reqBody.BackupWindow = String(window)
+ reqBody.BackupWindow = Ptr(window)
}
reqBodyData, err := json.Marshal(reqBody)
if err != nil {
@@ -964,10 +985,10 @@ func (c *ServerClient) AttachToNetwork(ctx context.Context, server *Server, opts
Network: opts.Network.ID,
}
if opts.IP != nil {
- reqBody.IP = String(opts.IP.String())
+ reqBody.IP = Ptr(opts.IP.String())
}
for _, aliasIP := range opts.AliasIPs {
- reqBody.AliasIPs = append(reqBody.AliasIPs, String(aliasIP.String()))
+ reqBody.AliasIPs = append(reqBody.AliasIPs, Ptr(aliasIP.String()))
}
reqBodyData, err := json.Marshal(reqBody)
if err != nil {
diff --git a/hcloud/server_test.go b/hcloud/server_test.go
index 81681cd..3b79c30 100644
--- a/hcloud/server_test.go
+++ b/hcloud/server_test.go
@@ -12,6 +12,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
+
"github.com/hetznercloud/hcloud-go/hcloud/schema"
)
@@ -341,7 +342,7 @@ func TestServersCreateWithoutSSHKeys(t *testing.T) {
Server: schema.Server{
ID: 1,
},
- RootPassword: String("test"),
+ RootPassword: Ptr("test"),
})
})
@@ -399,7 +400,7 @@ func TestServersCreateWithVolumes(t *testing.T) {
{ID: 1},
{ID: 2},
},
- Automount: Bool(true),
+ Automount: Ptr(true),
})
if err != nil {
t.Fatal(err)
@@ -846,7 +847,7 @@ func TestServersCreateWithLabels(t *testing.T) {
Server: schema.Server{
ID: 1,
},
- RootPassword: String("test"),
+ RootPassword: Ptr("test"),
})
})
@@ -892,7 +893,7 @@ func TestServersCreateWithoutStarting(t *testing.T) {
Name: "test",
ServerType: &ServerType{ID: 1},
Image: &Image{ID: 2},
- StartAfterCreate: Bool(false),
+ StartAfterCreate: Ptr(false),
})
if err != nil {
t.Fatal(err)
@@ -1022,7 +1023,16 @@ func TestServersDelete(t *testing.T) {
env := newTestEnv()
defer env.Teardown()
- env.Mux.HandleFunc("/servers/1", func(w http.ResponseWriter, r *http.Request) {})
+ env.Mux.HandleFunc("/servers/1", func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "DELETE" {
+ t.Error("expected DELETE")
+ }
+ json.NewEncoder(w).Encode(schema.ServerDeleteResponse{
+ Action: schema.Action{
+ ID: 2,
+ },
+ })
+ })
var (
ctx = context.Background()
@@ -1034,6 +1044,34 @@ func TestServersDelete(t *testing.T) {
}
}
+func TestServersDeleteWithResult(t *testing.T) {
+ env := newTestEnv()
+ defer env.Teardown()
+
+ env.Mux.HandleFunc("/servers/1", func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "DELETE" {
+ t.Error("expected DELETE")
+ }
+ json.NewEncoder(w).Encode(schema.ServerDeleteResponse{
+ Action: schema.Action{
+ ID: 2,
+ },
+ })
+ })
+
+ var (
+ ctx = context.Background()
+ server = &Server{ID: 1}
+ )
+ result, _, err := env.Client.Server.DeleteWithResult(ctx, server)
+ if err != nil {
+ t.Fatalf("Server.Delete failed: %s", err)
+ }
+ if result.Action.ID != 2 {
+ t.Errorf("unexpected action ID: %v", result.Action.ID)
+ }
+}
+
func TestServerClientUpdate(t *testing.T) {
var (
ctx = context.Background()
@@ -1336,7 +1374,7 @@ func TestServerClientCreateImageWithOptions(t *testing.T) {
ctx := context.Background()
opts := &ServerCreateImageOpts{
Type: ImageTypeBackup,
- Description: String("my backup"),
+ Description: Ptr("my backup"),
}
result, _, err := env.Client.Server.CreateImage(ctx, &Server{ID: 1}, opts)
if err != nil {
@@ -1773,8 +1811,8 @@ func TestServerClientChangeProtection(t *testing.T) {
})
opts := ServerChangeProtectionOpts{
- Delete: Bool(true),
- Rebuild: Bool(true),
+ Delete: Ptr(true),
+ Rebuild: Ptr(true),
}
action, _, err := env.Client.Server.ChangeProtection(ctx, server, opts)
if err != nil {
diff --git a/hcloud/volume.go b/hcloud/volume.go
index 93e221e..f939d89 100644
--- a/hcloud/volume.go
+++ b/hcloud/volume.go
@@ -210,7 +210,7 @@ func (c *VolumeClient) Create(ctx context.Context, opts VolumeCreateOpts) (Volum
reqBody.Labels = &opts.Labels
}
if opts.Server != nil {
- reqBody.Server = Int(opts.Server.ID)
+ reqBody.Server = Ptr(opts.Server.ID)
}
if opts.Location != nil {
if opts.Location.ID != 0 {
diff --git a/hcloud/volume_test.go b/hcloud/volume_test.go
index fdb046b..025ee17 100644
--- a/hcloud/volume_test.go
+++ b/hcloud/volume_test.go
@@ -438,8 +438,8 @@ func TestVolumeClientCreateWithAutomount(t *testing.T) {
Size: 42,
Server: &Server{ID: 1},
Labels: map[string]string{"key": "value"},
- Automount: Bool(true),
- Format: String("xfs"),
+ Automount: Ptr(true),
+ Format: Ptr("xfs"),
}
result, _, err := env.Client.Volume.Create(ctx, opts)
if err != nil {
More details
Historical runs
- failed: src/github.com/hetznercloud/hcloud-go/hcloud/helper.go:6:9: error: expected ‘(’
- nothing-to-do: Last upstream version 1.35.3 already imported.
- command-failed: Command 'SCHROOT=unstable-amd64-sbuild PYTHONPATH=/:/code:/code/breezy:/code/dulwich:/code/lintian-brush:/code/ognibuild:/code/silver-platter:/code/buildlog-consultant:/code/upstream-ontologist:/code/debmutate:/code/python-debian/lib:/usr/lib/python39.zip:/usr/lib/python3.9:/usr/lib/python3.9/lib-dynload:/usr/local/lib/python3.9/dist-packages:/usr/lib/python3/dist-packages /usr/bin/python3 -m janitor.dist --packaging=/tmp/janitoryzzjmr1v/golang-github-hetznercloud-hcloud-go/debian' returned non-zero exit status 1.
- command-failed: Command 'SCHROOT=unstable-amd64-sbuild PYTHONPATH=/:/code:/code/breezy:/code/dulwich:/code/lintian-brush:/code/ognibuild:/code/silver-platter:/code/buildlog-consultant:/code/upstream-ontologist:/code/debmutate:/code/python-debian/lib:/usr/lib/python39.zip:/usr/lib/python3.9:/usr/lib/python3.9/lib-dynload:/usr/local/lib/python3.9/dist-packages:/usr/lib/python3/dist-packages /usr/bin/python3 -m janitor.dist --packaging=/tmp/janitorltmw33nn/golang-github-hetznercloud-hcloud-go/debian' returned non-zero exit status 1.