mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-04-20 08:30:29 +00:00
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package hold
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// CloudMetadata contains region info from cloud metadata service
|
|
type CloudMetadata struct {
|
|
Region string
|
|
}
|
|
|
|
// metadataEndpoint is the cloud metadata service URL. Package-level var for test override.
|
|
var metadataEndpoint = "http://169.254.169.254"
|
|
|
|
// DetectCloudMetadata queries the instance metadata service (169.254.169.254)
|
|
// Currently supports UpCloud. Others can be added via PR.
|
|
func DetectCloudMetadata(ctx context.Context) (*CloudMetadata, error) {
|
|
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
|
defer cancel()
|
|
|
|
// Try UpCloud metadata format
|
|
if meta, err := detectUpCloud(ctx); err == nil {
|
|
return meta, nil
|
|
}
|
|
|
|
// Add other providers here (AWS, GCP, Azure, DigitalOcean, etc.)
|
|
// Contributors welcome!
|
|
|
|
return nil, nil // No metadata available
|
|
}
|
|
|
|
// detectUpCloud queries UpCloud's metadata service
|
|
func detectUpCloud(ctx context.Context) (*CloudMetadata, error) {
|
|
req, err := http.NewRequestWithContext(ctx, "GET", metadataEndpoint+"/metadata/v1.json", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
return nil, fmt.Errorf("metadata returned %d", resp.StatusCode)
|
|
}
|
|
|
|
var data struct {
|
|
CloudName string `json:"cloud_name"`
|
|
Region string `json:"region"`
|
|
}
|
|
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if data.CloudName != "upcloud" {
|
|
return nil, fmt.Errorf("not upcloud: %s", data.CloudName)
|
|
}
|
|
|
|
return &CloudMetadata{
|
|
Region: data.Region,
|
|
}, nil
|
|
}
|