jkawamoto/roadie

View on GitHub
cloud/azure/compute.go

Summary

Maintainability
A
1 hr
Test Coverage
//
// cloud/azure/compute.go
//
// Copyright (c) 2016-2017 Junpei Kawamoto
//
// This file is part of Roadie.
//
// Roadie is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Roadie is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Roadie.  If not, see <http://www.gnu.org/licenses/>.
//

package azure

import (
    "context"
    "fmt"
    "io/ioutil"
    "log"

    httptransport "github.com/go-openapi/runtime/client"
    "github.com/go-openapi/strfmt"
    "github.com/jkawamoto/roadie/cloud"
    client "github.com/jkawamoto/roadie/cloud/azure/compute/client"
    "github.com/jkawamoto/roadie/cloud/azure/compute/client/virtual_machine_images"
    "github.com/jkawamoto/roadie/cloud/azure/compute/client/virtual_machine_sizes"
)

const (
    // ComputeAPIVersion defines API version of compute service.
    ComputeAPIVersion = "2016-04-30-preview"
)

// ComputeService provides an interface for Azure's compute service.
type ComputeService struct {
    client *client.ComputeManagementClient
    Config *Config
    Logger *log.Logger
}

// Entry is an entry of lists.
type Entry struct {
    ID   string
    Name string
}

// NewComputeService creates a new compute service interface assosiated with
// a given configuration.
func NewComputeService(ctx context.Context, cfg *Config, logger *log.Logger) (s *ComputeService, err error) {

    if logger == nil {
        logger = log.New(ioutil.Discard, "", log.LstdFlags)
    }

    // Create a management client.
    cli := client.NewHTTPClient(strfmt.NewFormats())
    s = &ComputeService{
        client: cli,
        Config: cfg,
        Logger: logger,
    }
    return

}

// AvailableRegions returns a list of available regions.
func (s *ComputeService) AvailableRegions(ctx context.Context) (regions []cloud.Region, err error) {
    s.Logger.Println("Retrieving available regions")
    regions, err = Locations(ctx, &s.Config.Token, s.Config.SubscriptionID)
    if err != nil {
        s.Logger.Println("Cannot retrieve available regions")
    } else {
        s.Logger.Println("Retrieved available regions")
    }
    return
}

// AvailableMachineTypes returns a list of available machine types.
func (s *ComputeService) AvailableMachineTypes(ctx context.Context) (types []cloud.MachineType, err error) {

    s.Logger.Println("Retrieving available machine types")
    res, err := s.client.VirtualMachineSizes.VirtualMachineSizesList(
        virtual_machine_sizes.NewVirtualMachineSizesListParamsWithContext(ctx).
            WithAPIVersion(ComputeAPIVersion).
            WithSubscriptionID(s.Config.SubscriptionID).
            WithLocation(s.Config.Location), httptransport.BearerToken(s.Config.Token.AccessToken))
    if err != nil {
        err = NewAPIError(err)
        s.Logger.Println("Cannot retrieve available machine types:", err.Error())
        return
    }

    types = make([]cloud.MachineType, len(res.Payload.Value))
    for i, v := range res.Payload.Value {
        types[i] = cloud.MachineType{
            Name:        v.Name,
            Description: fmt.Sprintf("%v Cores, %v MB RAM", v.NumberOfCores, v.MemoryInMB),
        }
    }
    s.Logger.Println("Retrieved available machine types")
    return

}

// ImagePublishers retrieves a set of image publishers.
func (s *ComputeService) ImagePublishers(ctx context.Context) (publishers []Entry, err error) {

    s.Logger.Println("Retrieving image publishers")
    res, err := s.client.VirtualMachineImages.VirtualMachineImagesListPublishers(
        virtual_machine_images.NewVirtualMachineImagesListPublishersParamsWithContext(ctx).
            WithAPIVersion(ComputeAPIVersion).
            WithSubscriptionID(s.Config.SubscriptionID).
            WithLocation(s.Config.Location), httptransport.BearerToken(s.Config.Token.AccessToken))
    if err != nil {
        err = NewAPIError(err)
        s.Logger.Println("Cannot retrieve image publishers:", err.Error())
        return
    }

    publishers = make([]Entry, len(res.Payload))
    for i, v := range res.Payload {
        publishers[i] = Entry{
            ID:   v.ID,
            Name: *v.Name,
        }
    }
    s.Logger.Println("Retrieved image publishers")
    return

}

// ImageOffers retrieves a set of offers provided by a given publisher.
func (s *ComputeService) ImageOffers(ctx context.Context, publisher string) (offers []Entry, err error) {

    s.Logger.Println("Retrieving image offers of ", publisher)
    res, err := s.client.VirtualMachineImages.VirtualMachineImagesListOffers(
        virtual_machine_images.NewVirtualMachineImagesListOffersParamsWithContext(ctx).
            WithAPIVersion(ComputeAPIVersion).
            WithSubscriptionID(s.Config.SubscriptionID).
            WithLocation(s.Config.Location).
            WithPublisherName(publisher), httptransport.BearerToken(s.Config.Token.AccessToken))
    if err != nil {
        err = NewAPIError(err)
        s.Logger.Println("Cannot retrieve image offers:", err.Error())
        return
    }

    offers = make([]Entry, len(res.Payload))
    for i, v := range res.Payload {
        offers[i] = Entry{
            ID:   v.ID,
            Name: *v.Name,
        }
    }
    s.Logger.Println("Retrieved image offers")
    return

}

// ImageSkus retrieves a set of skus provded by a given publisher and offer.
func (s *ComputeService) ImageSkus(ctx context.Context, publisherName, offer string) (skus []Entry, err error) {

    s.Logger.Println("Retrieving image skus of ", publisherName, ":", offer)
    res, err := s.client.VirtualMachineImages.VirtualMachineImagesListSkus(
        virtual_machine_images.NewVirtualMachineImagesListSkusParamsWithContext(ctx).
            WithAPIVersion(ComputeAPIVersion).
            WithSubscriptionID(s.Config.SubscriptionID).
            WithLocation(s.Config.Location).
            WithPublisherName(publisherName).
            WithOffer(offer), httptransport.BearerToken(s.Config.Token.AccessToken))
    if err != nil {
        err = NewAPIError(err)
        s.Logger.Println("Cannot retrieve image skus:", err.Error())
        return
    }

    skus = make([]Entry, len(res.Payload))
    for i, v := range res.Payload {
        skus[i] = Entry{
            ID:   v.ID,
            Name: *v.Name,
        }
    }
    s.Logger.Println("Retrieved image skus")
    return

}

// ImageVersions retrieves a set of versions provided by a given publisher,
// offer, and skus.
func (s *ComputeService) ImageVersions(ctx context.Context, publisherName, offer, skus string) (versions []Entry, err error) {

    s.Logger.Println("Retrieving image versions of ", publisherName, ":", offer, ":", skus)
    res, err := s.client.VirtualMachineImages.VirtualMachineImagesList(
        virtual_machine_images.NewVirtualMachineImagesListParamsWithContext(ctx).
            WithAPIVersion(ComputeAPIVersion).
            WithSubscriptionID(s.Config.SubscriptionID).
            WithLocation(s.Config.Location).
            WithPublisherName(publisherName).
            WithOffer(offer).
            WithSkus(skus), httptransport.BearerToken(s.Config.Token.AccessToken))
    if err != nil {
        err = NewAPIError(err)
        s.Logger.Println("Cannot retrieve image versions:", err.Error())
        return
    }

    versions = make([]Entry, len(res.Payload))
    for i, v := range res.Payload {
        versions[i] = Entry{
            ID:   v.ID,
            Name: *v.Name,
        }
    }
    s.Logger.Println("REtrieved image versions")
    return

}

// ImageID retrieves an image ID.
func (s *ComputeService) ImageID(ctx context.Context, publisherName, offer, skus, version string) (id string, err error) {

    s.Logger.Println("Retrieving an image ID")
    res, err := s.client.VirtualMachineImages.VirtualMachineImagesGet(
        virtual_machine_images.NewVirtualMachineImagesGetParamsWithContext(ctx).
            WithAPIVersion(ComputeAPIVersion).
            WithSubscriptionID(s.Config.SubscriptionID).
            WithLocation(s.Config.Location).
            WithPublisherName(publisherName).
            WithOffer(offer).
            WithSkus(skus).
            WithVersion(version), httptransport.BearerToken(s.Config.Token.AccessToken))

    if err != nil {
        err = NewAPIError(err)
        s.Logger.Println("Cannot retrieve an image ID:", err.Error())
        return
    }

    s.Logger.Println("Retreived the image ID")
    return res.Payload.ID, nil

}