Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Hetzner public IPv4 and IPv6 configuration #5001

Merged
merged 2 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cluster-autoscaler/cloudprovider/hetzner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ The cluster autoscaler for Hetzner Cloud scales worker nodes.

`HCLOUD_SSH_KEY` Default empty , This SSH Key will have access to the fresh created server, @see https://docs.hetzner.cloud/#ssh-keys

`HCLOUD_PUBLIC_IPV4` Default true , Whether the server is created with a public IPv4 address or not, @see https://docs.hetzner.cloud/#primary-ips

`HCLOUD_PUBLIC_IPV6` Default true , Whether the server is created with a public IPv6 address or not, @see https://docs.hetzner.cloud/#primary-ips

Node groups must be defined with the `--nodes=<min-servers>:<max-servers>:<instance-type>:<region>:<name>` flag.

Multiple flags will create multiple node pools. For example:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,17 @@ func (c *CertificateClient) Get(ctx context.Context, idOrName string) (*Certific
type CertificateListOpts struct {
ListOpts
Name string
Sort []string
}

func (l CertificateListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -31,10 +32,9 @@ import (
"strings"
"time"

"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/hetzner/hcloud-go/hcloud/internal/instrumentation"

"github.com/prometheus/client_golang/prometheus"

"golang.org/x/net/http/httpguts"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/hetzner/hcloud-go/hcloud/internal/instrumentation"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/hetzner/hcloud-go/hcloud/schema"
)

Expand Down Expand Up @@ -70,6 +70,7 @@ func ExponentialBackoff(b float64, d time.Duration) BackoffFunc {
type Client struct {
endpoint string
token string
tokenValid bool
pollInterval time.Duration
backoffFunc BackoffFunc
httpClient *http.Client
Expand Down Expand Up @@ -97,6 +98,7 @@ type Client struct {
Volume VolumeClient
PlacementGroup PlacementGroupClient
RDNS RDNSClient
PrimaryIP PrimaryIPClient
}

// A ClientOption is used to configure a Client.
Expand All @@ -113,6 +115,7 @@ func WithEndpoint(endpoint string) ClientOption {
func WithToken(token string) ClientOption {
return func(client *Client) {
client.token = token
client.tokenValid = httpguts.ValidHeaderFieldValue(token)
}
}

Expand Down Expand Up @@ -167,6 +170,7 @@ func WithInstrumentation(registry *prometheus.Registry) ClientOption {
func NewClient(options ...ClientOption) *Client {
client := &Client{
endpoint: Endpoint,
tokenValid: true,
httpClient: &http.Client{},
backoffFunc: ExponentialBackoff(2, 500*time.Millisecond),
pollInterval: 500 * time.Millisecond,
Expand Down Expand Up @@ -200,6 +204,7 @@ func NewClient(options ...ClientOption) *Client {
client.Firewall = FirewallClient{client: client}
client.PlacementGroup = PlacementGroupClient{client: client}
client.RDNS = RDNSClient{client: client}
client.PrimaryIP = PrimaryIPClient{client: client}

return client
}
Expand All @@ -213,9 +218,13 @@ func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Re
return nil, err
}
req.Header.Set("User-Agent", c.userAgent)
if c.token != "" {

if !c.tokenValid {
return nil, errors.New("Authorization token contains invalid characters")
} else if c.token != "" {
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.token))
}

if body != nil {
req.Header.Set("Content-Type", "application/json")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,17 @@ func (c *DatacenterClient) Get(ctx context.Context, idOrName string) (*Datacente
type DatacenterListOpts struct {
ListOpts
Name string
Sort []string
}

func (l DatacenterListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ const (
ErrorCodeMaintenance ErrorCode = "maintenance" // Cannot perform operation due to maintenance
ErrorCodeConflict ErrorCode = "conflict" // The resource has changed during the request, please retry
ErrorCodeRobotUnavailable ErrorCode = "robot_unavailable" // Robot was not available. The caller may retry the operation after a short delay
ErrorUnsupportedError ErrorCode = "unsupported_error" // The gives resource does not support this
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
ErrorCodeInvalidServerType ErrorCode = "invalid_server_type" // The server type does not fit for the given server or is deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,17 @@ func (c *FirewallClient) Get(ctx context.Context, idOrName string) (*Firewall, *
type FirewallListOpts struct {
ListOpts
Name string
Sort []string
}

func (l FirewallListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,17 @@ func (c *FloatingIPClient) Get(ctx context.Context, idOrName string) (*FloatingI
type FloatingIPListOpts struct {
ListOpts
Name string
Sort []string
}

func (l FloatingIPListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ limitations under the License.
package hcloud

// Version is the library's version following Semantic Versioning.
const Version = "1.32.0"
const Version = "1.35.0"
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,17 @@ func (c *ISOClient) Get(ctx context.Context, idOrName string) (*ISO, *Response,
type ISOListOpts struct {
ListOpts
Name string
Sort []string
}

func (l ISOListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package hcloud

import (
"fmt"
"regexp"
)

var keyRegexp = regexp.MustCompile(
`^([a-z0-9A-Z]((?:[\-_.]|[a-z0-9A-Z]){0,253}[a-z0-9A-Z])?/)?[a-z0-9A-Z]((?:[\-_.]|[a-z0-9A-Z]|){0,62}[a-z0-9A-Z])?$`)
var valueRegexp = regexp.MustCompile(`^([a-z0-9A-Z](?:[\-_.]|[a-z0-9A-Z]){0,62})?[a-z0-9A-Z]$`)

func ValidateResourceLabels(labels map[string]interface{}) (bool, error) {
for k, v := range labels {
if match := keyRegexp.MatchString(k); !match {
return false, fmt.Errorf("label key '%s' is not correctly formatted", k)
}

if match := valueRegexp.MatchString(v.(string)); !match {
return false, fmt.Errorf("label value '%s' (key: %s) is not correctly formatted", v, k)
}
}
return true, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,17 @@ func (c *LoadBalancerClient) Get(ctx context.Context, idOrName string) (*LoadBal
type LoadBalancerListOpts struct {
ListOpts
Name string
Sort []string
}

func (l LoadBalancerListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,17 @@ func (c *LoadBalancerTypeClient) Get(ctx context.Context, idOrName string) (*Loa
type LoadBalancerTypeListOpts struct {
ListOpts
Name string
Sort []string
}

func (l LoadBalancerTypeListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,17 @@ func (c *LocationClient) Get(ctx context.Context, idOrName string) (*Location, *
type LocationListOpts struct {
ListOpts
Name string
Sort []string
}

func (l LocationListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package metadata

import (
"fmt"
"io/ioutil"
"net"
"net/http"
Expand Down Expand Up @@ -88,12 +89,16 @@ func (c *Client) get(path string) (string, error) {
if err != nil {
return "", err
}
body, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
resp.Body.Close()
return string(body), nil
body := string(bodyBytes)
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return body, fmt.Errorf("response status was %d", resp.StatusCode)
}
return body, nil
}

// IsHcloudServer checks if the currently called server is a hcloud server by calling a metadata endpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,17 @@ func (c *NetworkClient) Get(ctx context.Context, idOrName string) (*Network, *Re
type NetworkListOpts struct {
ListOpts
Name string
Sort []string
}

func (l NetworkListOpts) values() url.Values {
vals := l.ListOpts.values()
if l.Name != "" {
vals.Add("name", l.Name)
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type PlacementGroupListOpts struct {
ListOpts
Name string
Type PlacementGroupType
Sort []string
}

func (l PlacementGroupListOpts) values() url.Values {
Expand All @@ -106,6 +107,9 @@ func (l PlacementGroupListOpts) values() url.Values {
if l.Type != "" {
vals.Add("type", string(l.Type))
}
for _, sort := range l.Sort {
vals.Add("sort", sort)
}
return vals
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Pricing struct {
Image ImagePricing
FloatingIP FloatingIPPricing
FloatingIPs []FloatingIPTypePricing
PrimaryIPs []PrimaryIPPricing
Traffic TrafficPricing
ServerBackup ServerBackupPricing
ServerTypes []ServerTypePricing
Expand All @@ -44,6 +45,14 @@ type Price struct {
Gross string
}

// PrimaryIPPrice represents a price. Net amount and gross amount are
// specified as strings and it is the user's responsibility to convert them to
// appropriate types for calculations.
type PrimaryIPPrice struct {
Net string
Gross string
}

// ImagePricing provides pricing information for imaegs.
type ImagePricing struct {
PerGBMonth Price
Expand All @@ -60,6 +69,20 @@ type FloatingIPTypePricing struct {
Pricings []FloatingIPTypeLocationPricing
}

// PrimaryIPTypePricing defines the schema of pricing information for a primary IP
// type at a datacenter.
type PrimaryIPTypePricing struct {
Datacenter string
Hourly PrimaryIPPrice
Monthly PrimaryIPPrice
}

// PrimaryIPTypePricing provides pricing information for PrimaryIPs
type PrimaryIPPricing struct {
Type string
Pricings []PrimaryIPTypePricing
}

// FloatingIPTypeLocationPricing provides pricing information for a Floating IP type
// at a location.
type FloatingIPTypeLocationPricing struct {
Expand Down
Loading