feat: hcloud location properties

Receive regian/zone from metadata server.

Signed-off-by: Serge Logvinov <serge.logvinov@sinextra.dev>
Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
This commit is contained in:
Serge Logvinov 2022-11-21 21:54:03 +00:00 committed by Andrey Smirnov
parent 6bce06f622
commit a58c3d6699
No known key found for this signature in database
GPG Key ID: 7B26396447AB6DFD
4 changed files with 42 additions and 44 deletions

View File

@ -136,6 +136,8 @@ func (h *Hcloud) ParseMetadata(unmarshalledNetworkConfig *NetworkConfig, metadat
networkConfig.Metadata = &runtimeres.PlatformMetadataSpec{ networkConfig.Metadata = &runtimeres.PlatformMetadataSpec{
Platform: h.Name(), Platform: h.Name(),
Hostname: metadata.Hostname, Hostname: metadata.Hostname,
Region: metadata.Region,
Zone: metadata.AvailabilityZone,
InstanceID: metadata.InstanceID, InstanceID: metadata.InstanceID,
ProviderID: fmt.Sprintf("hcloud://%s", metadata.InstanceID), ProviderID: fmt.Sprintf("hcloud://%s", metadata.InstanceID),
} }

View File

@ -25,9 +25,11 @@ func TestParseMetadata(t *testing.T) {
h := &hcloud.Hcloud{} h := &hcloud.Hcloud{}
metadata := &hcloud.MetadataConfig{ metadata := &hcloud.MetadataConfig{
Hostname: "talos.fqdn", Hostname: "talos.fqdn",
PublicIPv4: "1.2.3.4", PublicIPv4: "1.2.3.4",
InstanceID: "0", InstanceID: "0",
Region: "hel1",
AvailabilityZone: "hel1-dc2",
} }
var m hcloud.NetworkConfig var m hcloud.NetworkConfig

View File

@ -7,32 +7,21 @@ package hcloud
import ( import (
"context" "context"
stderrors "errors" stderrors "errors"
"log" "fmt"
"strings"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/errors" "github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/errors"
"github.com/siderolabs/talos/pkg/download" "github.com/siderolabs/talos/pkg/download"
) )
const ( const (
// HCloudExternalIPEndpoint is the local hcloud endpoint for the external IP. // HCloudMetadataEndpoint is the local HCloud metadata endpoint.
HCloudExternalIPEndpoint = "http://169.254.169.254/hetzner/v1/metadata/public-ipv4" HCloudMetadataEndpoint = "http://169.254.169.254/hetzner/v1/metadata"
// HCloudNetworkEndpoint is the local hcloud endpoint for the network-config. // HCloudNetworkEndpoint is the local HCloud metadata endpoint for the network-config.
HCloudNetworkEndpoint = "http://169.254.169.254/hetzner/v1/metadata/network-config" HCloudNetworkEndpoint = "http://169.254.169.254/hetzner/v1/metadata/network-config"
// HCloudHostnameEndpoint is the local hcloud endpoint for the hostname. // HCloudUserDataEndpoint is the local HCloud metadata endpoint for the config.
HCloudHostnameEndpoint = "http://169.254.169.254/hetzner/v1/metadata/hostname"
// HCloudInstanceIDEndpoint is the local hcloud endpoint for the instance-id.
HCloudInstanceIDEndpoint = "http://169.254.169.254/hetzner/v1/metadata/instance-id"
// HCloudRegionEndpoint is the local hcloud endpoint for the region.
HCloudRegionEndpoint = "http://169.254.169.254/hetzner/v1/metadata/region"
// HCloudZoneEndpoint is the local hcloud endpoint for the zone.
HCloudZoneEndpoint = "http://169.254.169.254/hetzner/v1/metadata/availability-zone"
// HCloudUserDataEndpoint is the local hcloud endpoint for the config.
HCloudUserDataEndpoint = "http://169.254.169.254/hetzner/v1/userdata" HCloudUserDataEndpoint = "http://169.254.169.254/hetzner/v1/userdata"
) )
@ -40,7 +29,7 @@ const (
type MetadataConfig struct { type MetadataConfig struct {
Hostname string `yaml:"hostname,omitempty"` Hostname string `yaml:"hostname,omitempty"`
Region string `yaml:"region,omitempty"` Region string `yaml:"region,omitempty"`
AvailabilityZone string `json:"availability-zone,omitempty"` AvailabilityZone string `yaml:"availability-zone,omitempty"`
InstanceID string `yaml:"instance-id,omitempty"` InstanceID string `yaml:"instance-id,omitempty"`
PublicIPv4 string `yaml:"public-ipv4,omitempty"` PublicIPv4 string `yaml:"public-ipv4,omitempty"`
} }
@ -63,37 +52,40 @@ type NetworkConfig struct {
} `yaml:"config"` } `yaml:"config"`
} }
func (h *Hcloud) getMetadata(ctx context.Context) (*MetadataConfig, error) { func (h *Hcloud) getMetadata(ctx context.Context) (metadata *MetadataConfig, err error) {
log.Printf("fetching hostname from: %q", HCloudHostnameEndpoint) getMetadataKey := func(key string) (string, error) {
res, metaerr := download.Download(ctx, fmt.Sprintf("%s/%s", HCloudMetadataEndpoint, key),
download.WithErrorOnNotFound(errors.ErrNoConfigSource),
download.WithErrorOnEmptyResponse(errors.ErrNoConfigSource))
if metaerr != nil && !stderrors.Is(metaerr, errors.ErrNoConfigSource) {
return "", fmt.Errorf("failed to fetch %q from IMDS: %w", key, metaerr)
}
host, err := download.Download(ctx, HCloudHostnameEndpoint, return string(res), nil
download.WithErrorOnNotFound(errors.ErrNoHostname), }
download.WithErrorOnEmptyResponse(errors.ErrNoHostname))
if err != nil && !stderrors.Is(err, errors.ErrNoHostname) { metadata = &MetadataConfig{}
if metadata.Hostname, err = getMetadataKey("hostname"); err != nil {
return nil, err return nil, err
} }
log.Printf("fetching instance-id from: %q", HCloudInstanceIDEndpoint) if metadata.InstanceID, err = getMetadataKey("instance-id"); err != nil {
instanceID, err := download.Download(ctx, HCloudInstanceIDEndpoint,
download.WithErrorOnNotFound(errors.ErrNoHostname),
download.WithErrorOnEmptyResponse(errors.ErrNoHostname))
if err != nil && !stderrors.Is(err, errors.ErrNoHostname) {
return nil, err return nil, err
} }
log.Printf("fetching externalIP from: %q", HCloudExternalIPEndpoint) if metadata.AvailabilityZone, err = getMetadataKey("availability-zone"); err != nil {
extIP, err := download.Download(ctx, HCloudExternalIPEndpoint,
download.WithErrorOnNotFound(errors.ErrNoExternalIPs),
download.WithErrorOnEmptyResponse(errors.ErrNoExternalIPs))
if err != nil && !stderrors.Is(err, errors.ErrNoExternalIPs) {
return nil, err return nil, err
} }
return &MetadataConfig{ // Original CCM/CSI uses first part of availability-zone to define region name.
Hostname: string(host), // But metadata has different value.
InstanceID: string(instanceID), // We will follow official behavior.
PublicIPv4: string(extIP), metadata.Region = strings.SplitN(metadata.AvailabilityZone, "-", 2)[0]
}, nil
if metadata.PublicIPv4, err = getMetadataKey("public-ipv4"); err != nil {
return nil, err
}
return metadata, nil
} }

View File

@ -44,5 +44,7 @@ externalIPs:
metadata: metadata:
platform: hcloud platform: hcloud
hostname: talos.fqdn hostname: talos.fqdn
region: hel1
zone: hel1-dc2
instanceId: "0" instanceId: "0"
providerId: hcloud://0 providerId: hcloud://0