or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
golangpkg:golang/cloud.google.com/go/compute@v1.53.0

docs

index.mdmetadata.mdtypes.md
tile.json

tessl/golang-cloud-google-com--go--compute

tessl install tessl/golang-cloud-google-com--go--compute@1.53.0

Go client library for Google Cloud Compute Engine API providing programmatic access to manage virtual machines, disks, networks, and other compute resources

metadata.mddocs/

Metadata Package

The cloud.google.com/go/compute/metadata package provides a client library for accessing the GCE metadata service from within running instances. The metadata service provides information about the current instance, project, network configuration, and service accounts.

Import

import "cloud.google.com/go/compute/metadata"

Instance Detection

// OnGCE reports whether the code is running on Google Compute Engine
func OnGCE() bool

// OnGCEWithContext reports whether the code is running on Google Compute Engine with context support
func OnGCEWithContext(ctx context.Context) bool

Example:

import "cloud.google.com/go/compute/metadata"

if metadata.OnGCE() {
    fmt.Println("Running on GCE")
    // Use metadata service
} else {
    fmt.Println("Not running on GCE")
    // Use alternative configuration
}

Project Information

// ProjectID returns the project ID
func ProjectID() (string, error)

// ProjectIDWithContext returns the project ID with context support
func ProjectIDWithContext(ctx context.Context) (string, error)

// NumericProjectID returns the numeric project ID
func NumericProjectID() (string, error)

// NumericProjectIDWithContext returns the numeric project ID with context support
func NumericProjectIDWithContext(ctx context.Context) (string, error)

Example:

import (
    "context"
    "cloud.google.com/go/compute/metadata"
)

ctx := context.Background()

projectID, err := metadata.ProjectIDWithContext(ctx)
if err != nil {
    // handle error
}
fmt.Printf("Project ID: %s\n", projectID)

numericProjectID, err := metadata.NumericProjectIDWithContext(ctx)
if err != nil {
    // handle error
}
fmt.Printf("Numeric Project ID: %s\n", numericProjectID)

Project Metadata

// ProjectAttributes returns the list of project-level custom metadata keys
func ProjectAttributes() ([]string, error)

// ProjectAttributesWithContext returns the list of project-level custom metadata keys with context support
func ProjectAttributesWithContext(ctx context.Context) ([]string, error)

// ProjectAttributeValue returns the value of a project-level custom metadata attribute
func ProjectAttributeValue(key string) (string, error)

// ProjectAttributeValueWithContext returns the value of a project-level custom metadata attribute with context support
func ProjectAttributeValueWithContext(ctx context.Context, key string) (string, error)

Example:

ctx := context.Background()

// Get project-level custom metadata value
sshKeys, err := metadata.ProjectAttributeValueWithContext(ctx, "ssh-keys")
if err != nil {
    // handle error (attribute may not exist)
}
if sshKeys != "" {
    fmt.Printf("Project SSH keys: %s\n", sshKeys)
}

// List all project-level custom attributes
attrs, err := metadata.ProjectAttributesWithContext(ctx)
if err != nil {
    // handle error
}
fmt.Printf("Project-level custom attributes: %v\n", attrs)

Instance Information

// InstanceID returns the instance ID
func InstanceID() (string, error)

// InstanceIDWithContext returns the instance ID with context support
func InstanceIDWithContext(ctx context.Context) (string, error)

// InstanceName returns the instance name
func InstanceName() (string, error)

// InstanceNameWithContext returns the instance name with context support
func InstanceNameWithContext(ctx context.Context) (string, error)

// Hostname returns the instance hostname
func Hostname() (string, error)

// HostnameWithContext returns the instance hostname with context support
func HostnameWithContext(ctx context.Context) (string, error)

// Zone returns the zone name (e.g., "us-central1-a")
func Zone() (string, error)

// ZoneWithContext returns the zone name with context support
func ZoneWithContext(ctx context.Context) (string, error)

Example:

ctx := context.Background()

instanceID, err := metadata.InstanceIDWithContext(ctx)
if err != nil {
    // handle error
}

instanceName, err := metadata.InstanceNameWithContext(ctx)
if err != nil {
    // handle error
}

zone, err := metadata.ZoneWithContext(ctx)
if err != nil {
    // handle error
}

fmt.Printf("Instance: %s (ID: %s) in zone %s\n", instanceName, instanceID, zone)

Network Information

// InternalIP returns the instance's internal IP address
func InternalIP() (string, error)

// InternalIPWithContext returns the instance's internal IP with context support
func InternalIPWithContext(ctx context.Context) (string, error)

// ExternalIP returns the instance's external IP address
func ExternalIP() (string, error)

// ExternalIPWithContext returns the instance's external IP with context support
func ExternalIPWithContext(ctx context.Context) (string, error)

Example:

ctx := context.Background()

internalIP, err := metadata.InternalIPWithContext(ctx)
if err != nil {
    // handle error
}
fmt.Printf("Internal IP: %s\n", internalIP)

externalIP, err := metadata.ExternalIPWithContext(ctx)
if err != nil {
    // handle error (instance may not have external IP)
}
if externalIP != "" {
    fmt.Printf("External IP: %s\n", externalIP)
}

Instance Metadata

// InstanceTags returns the instance's tags
func InstanceTags() ([]string, error)

// InstanceTagsWithContext returns the instance's tags with context support
func InstanceTagsWithContext(ctx context.Context) ([]string, error)

// InstanceAttributes returns the list of custom metadata keys
func InstanceAttributes() ([]string, error)

// InstanceAttributesWithContext returns the list of custom metadata keys with context support
func InstanceAttributesWithContext(ctx context.Context) ([]string, error)

// InstanceAttributeValue returns the value of a custom metadata attribute
func InstanceAttributeValue(key string) (string, error)

// InstanceAttributeValueWithContext returns the value of a custom metadata attribute with context support
func InstanceAttributeValueWithContext(ctx context.Context, key string) (string, error)

Example:

ctx := context.Background()

// Get all tags
tags, err := metadata.InstanceTagsWithContext(ctx)
if err != nil {
    // handle error
}
fmt.Printf("Tags: %v\n", tags)

// Get custom metadata value
startupScript, err := metadata.InstanceAttributeValueWithContext(ctx, "startup-script")
if err != nil {
    // handle error (attribute may not exist)
}
if startupScript != "" {
    fmt.Printf("Startup script: %s\n", startupScript)
}

// List all custom attributes
attrs, err := metadata.InstanceAttributesWithContext(ctx)
if err != nil {
    // handle error
}
fmt.Printf("Custom attributes: %v\n", attrs)

Service Account Information

// Scopes returns the OAuth2 scopes for a service account
func Scopes(serviceAccount string) ([]string, error)

// ScopesWithContext returns the OAuth2 scopes for a service account with context support
func ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error)

// Email returns the email address for a service account
func Email(serviceAccount string) (string, error)

// EmailWithContext returns the email address for a service account with context support
func EmailWithContext(ctx context.Context, serviceAccount string) (string, error)

Example:

ctx := context.Background()

// Use "default" for the default service account
email, err := metadata.EmailWithContext(ctx, "default")
if err != nil {
    // handle error
}
fmt.Printf("Service account email: %s\n", email)

scopes, err := metadata.ScopesWithContext(ctx, "default")
if err != nil {
    // handle error
}
fmt.Printf("Service account scopes: %v\n", scopes)

Generic Metadata Access

// Get retrieves arbitrary metadata by path suffix
func Get(suffix string) (string, error)

// GetWithContext retrieves arbitrary metadata by path suffix with context support
func GetWithContext(ctx context.Context, suffix string) (string, error)

Example:

ctx := context.Background()

// Get machine type
machineType, err := metadata.GetWithContext(ctx, "instance/machine-type")
if err != nil {
    // handle error
}
fmt.Printf("Machine type: %s\n", machineType)

// Get CPU platform
cpuPlatform, err := metadata.GetWithContext(ctx, "instance/cpu-platform")
if err != nil {
    // handle error
}
fmt.Printf("CPU platform: %s\n", cpuPlatform)

// Get network interface info
networkInterface, err := metadata.GetWithContext(ctx, "instance/network-interfaces/0/ip")
if err != nil {
    // handle error
}
fmt.Printf("Network interface IP: %s\n", networkInterface)

Metadata Watching

// Subscribe watches for changes to a metadata value and calls the provided function
func Subscribe(suffix string, fn func(v string, ok bool) error) error

// SubscribeWithContext watches for changes to a metadata value with context support
func SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) error

Example:

import (
    "context"
    "time"
)

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()

// Watch for changes to custom metadata
err := metadata.SubscribeWithContext(ctx, "instance/attributes/config", func(ctx context.Context, value string, ok bool) error {
    if ok {
        fmt.Printf("Config updated: %s\n", value)
        // React to configuration change
    } else {
        fmt.Println("Config attribute removed")
    }
    return nil
})
if err != nil {
    // handle error
}

Metadata Client Type

The Client type allows creating a custom metadata client with a specific HTTP client.

// Client represents a metadata client with custom configuration
type Client struct {
    // contains filtered or unexported fields
}

// NewClient creates a new metadata client with a custom HTTP client
func NewClient(c *http.Client) *Client

// NewWithOptions creates a new metadata client with custom options
func NewWithOptions(opts *Options) *Client

All package-level functions are available as methods on the Client:

// Client methods (mirrors package functions)
func (c *Client) OnGCEWithContext(ctx context.Context) bool
func (c *Client) ProjectID() (string, error)
func (c *Client) ProjectIDWithContext(ctx context.Context) (string, error)
func (c *Client) NumericProjectID() (string, error)
func (c *Client) NumericProjectIDWithContext(ctx context.Context) (string, error)
func (c *Client) ProjectAttributes() ([]string, error)
func (c *Client) ProjectAttributesWithContext(ctx context.Context) ([]string, error)
func (c *Client) ProjectAttributeValue(key string) (string, error)
func (c *Client) ProjectAttributeValueWithContext(ctx context.Context, key string) (string, error)
func (c *Client) InstanceID() (string, error)
func (c *Client) InstanceIDWithContext(ctx context.Context) (string, error)
func (c *Client) InstanceName() (string, error)
func (c *Client) InstanceNameWithContext(ctx context.Context) (string, error)
func (c *Client) Hostname() (string, error)
func (c *Client) HostnameWithContext(ctx context.Context) (string, error)
func (c *Client) Zone() (string, error)
func (c *Client) ZoneWithContext(ctx context.Context) (string, error)
func (c *Client) InternalIP() (string, error)
func (c *Client) InternalIPWithContext(ctx context.Context) (string, error)
func (c *Client) ExternalIP() (string, error)
func (c *Client) ExternalIPWithContext(ctx context.Context) (string, error)
func (c *Client) InstanceTags() ([]string, error)
func (c *Client) InstanceTagsWithContext(ctx context.Context) ([]string, error)
func (c *Client) InstanceAttributes() ([]string, error)
func (c *Client) InstanceAttributesWithContext(ctx context.Context) ([]string, error)
func (c *Client) InstanceAttributeValue(key string) (string, error)
func (c *Client) InstanceAttributeValueWithContext(ctx context.Context, key string) (string, error)
func (c *Client) Scopes(serviceAccount string) ([]string, error)
func (c *Client) ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error)
func (c *Client) Email(serviceAccount string) (string, error)
func (c *Client) EmailWithContext(ctx context.Context, serviceAccount string) (string, error)
func (c *Client) Get(suffix string) (string, error)
func (c *Client) GetWithContext(ctx context.Context, suffix string) (string, error)
func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error
func (c *Client) SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) error

Example - Custom Client:

import (
    "net/http"
    "time"
)

// Create custom HTTP client with timeout
httpClient := &http.Client{
    Timeout: 5 * time.Second,
}

// Create metadata client
metadataClient := metadata.NewClient(httpClient)

// Use client methods
projectID, err := metadataClient.ProjectID()
if err != nil {
    // handle error
}

instanceName, err := metadataClient.InstanceName()
if err != nil {
    // handle error
}

Metadata Options Type

// Options configures a metadata client
type Options struct {
    // Retry is a custom retry function
    Retry func(resp *http.Response) bool

    // Timeout is the request timeout duration
    Timeout time.Duration
}

Example - Client with Options:

import "time"

opts := &metadata.Options{
    Timeout: 10 * time.Second,
    Retry: func(resp *http.Response) bool {
        // Custom retry logic
        return resp.StatusCode == 503 || resp.StatusCode == 504
    },
}

client := metadata.NewWithOptions(opts)

Common Metadata Paths

The metadata service provides access to various information via different paths:

Project Metadata

  • project/project-id - Project ID
  • project/numeric-project-id - Numeric project ID
  • project/attributes/ - Project-level custom metadata

Instance Metadata

  • instance/id - Instance ID
  • instance/name - Instance name
  • instance/hostname - Instance hostname
  • instance/zone - Zone (full path)
  • instance/machine-type - Machine type (full path)
  • instance/cpu-platform - CPU platform
  • instance/tags - Instance tags
  • instance/attributes/ - Instance-level custom metadata

Network Metadata

  • instance/network-interfaces/0/ip - Primary internal IP
  • instance/network-interfaces/0/access-configs/0/external-ip - External IP
  • instance/network-interfaces/0/network - VPC network
  • instance/network-interfaces/0/subnetwork - Subnet

Service Account Metadata

  • instance/service-accounts/default/email - Service account email
  • instance/service-accounts/default/scopes - OAuth2 scopes
  • instance/service-accounts/default/token - Access token

Error Handling

Error Types

// NotDefinedError is returned when a metadata key is not defined
type NotDefinedError string

func (suffix NotDefinedError) Error() string

// Error represents an HTTP error from the metadata service
type Error struct {
    Code    int    // HTTP response status code
    Message string // Server response message
}

func (e *Error) Error() string

Metadata functions return errors when:

  • Not running on GCE
  • Metadata attribute doesn't exist (NotDefinedError)
  • Network timeout
  • Metadata service unavailable (Error with HTTP status code)

Example:

externalIP, err := metadata.ExternalIP()
if err != nil {
    // Check if it's a NotDefinedError
    if _, ok := err.(metadata.NotDefinedError); ok {
        fmt.Println("Instance has no external IP")
    } else if metaErr, ok := err.(*metadata.Error); ok {
        fmt.Printf("Metadata service error: %d - %s\n", metaErr.Code, metaErr.Message)
    } else {
        fmt.Printf("Error: %v\n", err)
    }
}

Best Practices

1. Use Context-Aware Functions

Always use the WithContext variants in production:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

projectID, err := metadata.ProjectIDWithContext(ctx)

2. Check OnGCE First

Verify code is running on GCE before using metadata:

if !metadata.OnGCE() {
    // Use alternative configuration
    return
}

// Proceed with metadata queries

3. Cache Metadata Values

Metadata values rarely change, cache them:

var (
    cachedProjectID string
    cacheOnce       sync.Once
)

func getProjectID() (string, error) {
    var err error
    cacheOnce.Do(func() {
        cachedProjectID, err = metadata.ProjectID()
    })
    return cachedProjectID, err
}

4. Handle Missing Attributes

Not all instances have all attributes:

startupScript, err := metadata.InstanceAttributeValue("startup-script")
if err != nil {
    // Attribute may not exist, use default
    startupScript = ""
}

Complete Usage Example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "cloud.google.com/go/compute/metadata"
)

func main() {
    // Check if running on GCE
    if !metadata.OnGCE() {
        log.Fatal("Not running on Google Compute Engine")
    }

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Get project information
    projectID, err := metadata.ProjectIDWithContext(ctx)
    if err != nil {
        log.Fatalf("Failed to get project ID: %v", err)
    }

    // Get instance information
    instanceName, err := metadata.InstanceNameWithContext(ctx)
    if err != nil {
        log.Fatalf("Failed to get instance name: %v", err)
    }

    zone, err := metadata.ZoneWithContext(ctx)
    if err != nil {
        log.Fatalf("Failed to get zone: %v", err)
    }

    // Get network information
    internalIP, err := metadata.InternalIPWithContext(ctx)
    if err != nil {
        log.Fatalf("Failed to get internal IP: %v", err)
    }

    // External IP might not exist
    externalIP, err := metadata.ExternalIPWithContext(ctx)
    if err != nil {
        externalIP = "none"
    }

    // Get service account
    email, err := metadata.EmailWithContext(ctx, "default")
    if err != nil {
        log.Fatalf("Failed to get service account: %v", err)
    }

    // Print all information
    fmt.Printf("Project: %s\n", projectID)
    fmt.Printf("Instance: %s\n", instanceName)
    fmt.Printf("Zone: %s\n", zone)
    fmt.Printf("Internal IP: %s\n", internalIP)
    fmt.Printf("External IP: %s\n", externalIP)
    fmt.Printf("Service Account: %s\n", email)
}