packer-cn/builder/azure/common/client/metadata.go

95 lines
2.3 KiB
Go

package client
import (
"fmt"
"net/http"
"time"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
)
// DefaultMetadataClient is the default instance metadata client for Azure. Replace this variable for testing purposes only
var DefaultMetadataClient = NewMetadataClient()
// MetadataClientAPI holds methods that Packer uses to get information about the current VM
type MetadataClientAPI interface {
GetComputeInfo() (*ComputeInfo, error)
}
// MetadataClientStub is an easy way to put a test hook in DefaultMetadataClient
type MetadataClientStub struct {
ComputeInfo
}
//GetComputeInfo implements MetadataClientAPI
func (s MetadataClientStub) GetComputeInfo() (*ComputeInfo, error) {
return &s.ComputeInfo, nil
}
// ComputeInfo defines the Azure VM metadata that is used in Packer
type ComputeInfo struct {
Name string
ResourceGroupName string
SubscriptionID string
Location string
}
// metadataClient implements MetadataClient
type metadataClient struct {
autorest.Sender
UserAgent string
}
var _ MetadataClientAPI = metadataClient{}
const imdsURL = "http://169.254.169.254/metadata/instance?api-version=2017-08-01"
// VMResourceID returns the resource ID of the current VM
func (client metadataClient) GetComputeInfo() (*ComputeInfo, error) {
req, err := autorest.CreatePreparer(
autorest.AsGet(),
autorest.WithHeader("Metadata", "true"),
autorest.WithUserAgent(client.UserAgent),
autorest.WithBaseURL(imdsURL),
).Prepare((&http.Request{}))
if err != nil {
return nil, err
}
res, err := autorest.SendWithSender(client, req,
autorest.DoRetryForDuration(1*time.Minute, 5*time.Second))
if err != nil {
return nil, err
}
var vminfo struct {
ComputeInfo `json:"compute"`
}
err = autorest.Respond(
res,
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByUnmarshallingJSON(&vminfo),
autorest.ByClosing())
if err != nil {
return nil, err
}
return &vminfo.ComputeInfo, nil
}
func (ci ComputeInfo) ResourceID() string {
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s",
ci.SubscriptionID,
ci.ResourceGroupName,
ci.Name,
)
}
// NewMetadataClient creates a new instance metadata client
func NewMetadataClient() MetadataClientAPI {
return metadataClient{
Sender: autorest.CreateSender(),
}
}