Add Azure client set for chroot builder

This commit is contained in:
Paul Meyer 2019-09-25 21:13:23 +00:00
parent 2ded8f25ec
commit f106adbd12
4 changed files with 208 additions and 0 deletions

View File

@ -0,0 +1,90 @@
package client
import (
"net/http"
"regexp"
"time"
"github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute"
"github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute/computeapi"
"github.com/Azure/go-autorest/autorest"
)
type AzureClientSet interface {
MetadataClient() MetadataClientAPI
DisksClient() computeapi.DisksClientAPI
ImagesClient() computeapi.ImagesClientAPI
VirtualMachinesClient() computeapi.VirtualMachinesClientAPI
VirtualMachineImagesClient() VirtualMachineImagesClientAPI
PollClient() autorest.Client
}
var subscriptionPathRegex = regexp.MustCompile(`/subscriptions/([[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12})`)
var _ AzureClientSet = &azureClientSet{}
type azureClientSet struct {
sender autorest.Sender
authorizer autorest.Authorizer
subscriptionID string
PollingDelay time.Duration
}
func New(c Config, say func(string)) (AzureClientSet, error) {
token, err := c.GetServicePrincipalToken(say, c.CloudEnvironment.ResourceManagerEndpoint)
if err != nil {
return nil, err
}
return &azureClientSet{
authorizer: autorest.NewBearerAuthorizer(token),
subscriptionID: c.SubscriptionID,
sender: http.DefaultClient,
PollingDelay: time.Second,
}, nil
}
func (s azureClientSet) configureAutorestClient(c *autorest.Client) {
c.Authorizer = s.authorizer
c.Sender = s.sender
}
func (s azureClientSet) MetadataClient() MetadataClientAPI {
return metadataClient{s.sender}
}
func (s azureClientSet) DisksClient() computeapi.DisksClientAPI {
c := compute.NewDisksClient(s.subscriptionID)
s.configureAutorestClient(&c.Client)
c.PollingDelay = s.PollingDelay
return c
}
func (s azureClientSet) ImagesClient() computeapi.ImagesClientAPI {
c := compute.NewImagesClient(s.subscriptionID)
s.configureAutorestClient(&c.Client)
c.PollingDelay = s.PollingDelay
return c
}
func (s azureClientSet) VirtualMachinesClient() computeapi.VirtualMachinesClientAPI {
c := compute.NewVirtualMachinesClient(s.subscriptionID)
s.configureAutorestClient(&c.Client)
c.PollingDelay = s.PollingDelay
return c
}
func (s azureClientSet) VirtualMachineImagesClient() VirtualMachineImagesClientAPI {
c := compute.NewVirtualMachineImagesClient(s.subscriptionID)
s.configureAutorestClient(&c.Client)
c.PollingDelay = s.PollingDelay
return virtualMachineImagesClientAPI{c}
}
func (s azureClientSet) PollClient() autorest.Client {
c := autorest.NewClientWithUserAgent("Packer-Azure-ClientSet")
s.configureAutorestClient(&c)
c.PollingDelay = time.Second / 3
return c
}

View File

@ -0,0 +1,57 @@
package client
import (
"context"
"fmt"
"github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute"
"github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/compute/computeapi"
"github.com/Azure/go-autorest/autorest/to"
"regexp"
"strings"
)
var platformImageRegex = regexp.MustCompile(`^[-_.a-zA-Z0-9]+:[-_.a-zA-Z0-9]+:[-_.a-zA-Z0-9]+:[-_.a-zA-Z0-9]+$`)
type VirtualMachineImagesClientAPI interface {
computeapi.VirtualMachineImagesClientAPI
// extensions
GetLatest(ctx context.Context, publisher, offer, sku, location string) (*compute.VirtualMachineImageResource, error)
}
var _ VirtualMachineImagesClientAPI = virtualMachineImagesClientAPI{}
type virtualMachineImagesClientAPI struct {
computeapi.VirtualMachineImagesClientAPI
}
func ParsePlatformImageURN(urn string) (image *PlatformImage, err error) {
if !platformImageRegex.Match([]byte(urn)) {
return nil, fmt.Errorf("%q is not a valid platform image specifier", urn)
}
parts := strings.Split(urn, ":")
return &PlatformImage{parts[0], parts[1], parts[2], parts[3]}, nil
}
func (c virtualMachineImagesClientAPI) GetLatest(ctx context.Context, publisher, offer, sku, location string) (*compute.VirtualMachineImageResource, error) {
result, err := c.List(ctx, location, publisher, offer, sku, "", to.Int32Ptr(1), "name desc")
if err != nil {
return nil, err
}
if result.Value == nil || len(*result.Value) == 0 {
return nil, fmt.Errorf("%s:%s:%s:latest could not be found in location %s", publisher, offer, sku, location)
}
return &(*result.Value)[0], nil
}
type PlatformImage struct {
Publisher, Offer, Sku, Version string
}
func (pi PlatformImage) URN() string {
return fmt.Sprintf("%s:%s:%s:%s",
pi.Publisher,
pi.Offer,
pi.Sku,
pi.Version)
}

View File

@ -0,0 +1,30 @@
package client
import (
"fmt"
"testing"
)
func Test_platformImageRegex(t *testing.T) {
for i, v := range []string{
"Publisher:Offer:Sku:Versions",
"Publisher:Offer-name:2.0_alpha:2.0.2019060122",
} {
t.Run(fmt.Sprintf("should_match_%d", i), func(t *testing.T) {
if !platformImageRegex.Match([]byte(v)) {
t.Fatalf("expected %q to match", v)
}
})
}
for i, v := range []string{
"Publ isher:Offer:Sku:Versions",
"Publ/isher:Offer-name:2.0_alpha:2.0.2019060122",
} {
t.Run(fmt.Sprintf("should_not_match_%d", i), func(t *testing.T) {
if platformImageRegex.Match([]byte(v)) {
t.Fatalf("did not expected %q to match", v)
}
})
}
}

View File

@ -0,0 +1,31 @@
package client
import (
"os"
"testing"
"net/http"
"errors"
"github.com/Azure/go-autorest/autorest/azure/auth"
)
func GetTestClientSet(t *testing.T) (AzureClientSet, error) {
if (os.Getenv("AZURE_INTEGRATION_TEST") == "") {
t.Skip("AZURE_INTEGRATION_TEST not set")
} else {
a, err := auth.NewAuthorizerFromEnvironment()
if err == nil {
cli := azureClientSet{}
cli.authorizer = a
cli.subscriptionID = os.Getenv("AZURE_SUBSCRIPTION_ID")
cli.PollingDelay = 0
cli.sender = http.DefaultClient
return cli, nil
} else {
t.Skipf("Could not create Azure client: %v", err)
}
}
return nil, errors.New("Couldn't create client set")
}