Add metadata client

pull/8185/head
Paul Meyer 7 years ago
parent 72fdce09ba
commit 2ded8f25ec

@ -0,0 +1,81 @@
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()
// MetadataClient holds methods that Packer uses to get information about the current VM
type MetadataClientAPI interface {
GetComputeInfo() (*ComputeInfo, error)
}
type ComputeInfo struct{
Name string
ResourceGroupName string
SubscriptionID string
Location string
}
// metadataClient implements MetadataClient
type metadataClient struct {
autorest.Sender
}
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.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(),
}
}

@ -0,0 +1,33 @@
package client
import (
"fmt"
"testing"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/hashicorp/packer/builder/azure/common"
"github.com/stretchr/testify/assert"
)
func Test_MetadataReturnsComputeInfo(t *testing.T) {
if !common.IsAzure() {
t.Skipf("Not running on Azure, skipping live IMDS test")
}
mdc := NewMetadataClient()
info, err := mdc.GetComputeInfo()
assert.Nil(t, err)
vm, err := azure.ParseResourceID(fmt.Sprintf(
"/subscriptions/%s"+
"/resourceGroups/%s"+
"/providers/Microsoft.Compute"+
"/virtualMachines/%s",
info.SubscriptionID,
info.ResourceGroupName,
info.Name))
assert.Nil(t, err, "%q is not parsable as an Azure resource info", info)
assert.Regexp(t, "^[0-9a-fA-F-]{36}$", vm.SubscriptionID)
t.Logf("VM: %+v", vm)
}
Loading…
Cancel
Save