restic/vendor/github.com/Azure/azure-sdk-for-go/services/classic/management/vmutils/integration_test.go
2018-03-30 11:42:11 +02:00

475 lines
14 KiB
Go

// +build go1.7
package vmutils
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import (
"encoding/base64"
"fmt"
"math/rand"
"testing"
"time"
"github.com/Azure/azure-sdk-for-go/services/classic/management"
"github.com/Azure/azure-sdk-for-go/services/classic/management/hostedservice"
"github.com/Azure/azure-sdk-for-go/services/classic/management/location"
"github.com/Azure/azure-sdk-for-go/services/classic/management/osimage"
storage "github.com/Azure/azure-sdk-for-go/services/classic/management/storageservice"
"github.com/Azure/azure-sdk-for-go/services/classic/management/testutils"
vm "github.com/Azure/azure-sdk-for-go/services/classic/management/virtualmachine"
vmimage "github.com/Azure/azure-sdk-for-go/services/classic/management/virtualmachineimage"
)
func TestDeployPlatformImage(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
role := NewVMConfiguration(vmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
GetLinuxTestImage(t, client).Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
GenerateName())
ConfigureForLinux(&role, "myvm", "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
testRoleConfiguration(t, client, role, location)
}
func TestDeployPlatformWindowsImage(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
role := NewVMConfiguration(vmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
GetWindowsTestImage(t, client).Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
GenerateName())
ConfigureForWindows(&role, vmname, "azureuser", GeneratePassword(), true, "")
ConfigureWinRMOverHTTP(&role)
ConfigureWinRMOverHTTPS(&role, "")
testRoleConfiguration(t, client, role, location)
}
func TestVMImageList(t *testing.T) {
client := testutils.GetTestClient(t)
vmic := vmimage.NewClient(client)
il, _ := vmic.ListVirtualMachineImages(vmimage.ListParameters{})
for _, im := range il.VMImages {
t.Logf("%s -%s", im.Name, im.Description)
}
}
func TestDeployPlatformOSImageCaptureRedeploy(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
role := NewVMConfiguration(vmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
GetLinuxTestImage(t, client).Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
GenerateName())
ConfigureForLinux(&role, "myvm", "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
t.Logf("Deploying VM: %s", vmname)
createRoleConfiguration(t, client, role, location)
t.Logf("Wait for deployment to enter running state")
vmc := vm.NewClient(client)
status := vm.DeploymentStatusDeploying
for status != vm.DeploymentStatusRunning {
deployment, err := vmc.GetDeployment(vmname, vmname)
if err != nil {
t.Error(err)
break
}
status = deployment.Status
}
t.Logf("Shutting down VM: %s", vmname)
if err := Await(client, func() (management.OperationID, error) {
return vmc.ShutdownRole(vmname, vmname, vmname, vm.PostShutdownActionStopped)
}); err != nil {
t.Error(err)
}
if err := WaitForDeploymentPowerState(client, vmname, vmname, vm.PowerStateStopped); err != nil {
t.Fatal(err)
}
imagename := GenerateName()
t.Logf("Capturing OSImage: %s", imagename)
if err := Await(client, func() (management.OperationID, error) {
return vmc.CaptureRole(vmname, vmname, vmname, imagename, imagename, nil)
}); err != nil {
t.Error(err)
}
im := GetUserOSImage(t, client, imagename)
t.Logf("Found image: %+v", im)
newvmname := GenerateName()
role = NewVMConfiguration(newvmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
im.Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, newvmname),
GenerateName())
ConfigureForLinux(&role, newvmname, "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
t.Logf("Deploying new VM from freshly captured OS image: %s", newvmname)
if err := Await(client, func() (management.OperationID, error) {
return vmc.CreateDeployment(role, vmname, vm.CreateDeploymentOptions{})
}); err != nil {
t.Error(err)
}
deleteHostedService(t, client, vmname)
}
func TestDeployPlatformVMImageCaptureRedeploy(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
role := NewVMConfiguration(vmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
GetLinuxTestImage(t, client).Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
GenerateName())
ConfigureForLinux(&role, "myvm", "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
t.Logf("Deploying VM: %s", vmname)
createRoleConfiguration(t, client, role, location)
t.Logf("Wait for deployment to enter running state")
vmc := vm.NewClient(client)
status := vm.DeploymentStatusDeploying
for status != vm.DeploymentStatusRunning {
deployment, err := vmc.GetDeployment(vmname, vmname)
if err != nil {
t.Error(err)
break
}
status = deployment.Status
}
t.Logf("Shutting down VM: %s", vmname)
if err := Await(client, func() (management.OperationID, error) {
return vmc.ShutdownRole(vmname, vmname, vmname, vm.PostShutdownActionStopped)
}); err != nil {
t.Error(err)
}
if err := WaitForDeploymentInstanceStatus(client, vmname, vmname, vm.InstanceStatusStoppedVM); err != nil {
t.Fatal(err)
}
imagename := GenerateName()
t.Logf("Capturing VMImage: %s", imagename)
if err := Await(client, func() (management.OperationID, error) {
return vmimage.NewClient(client).Capture(vmname, vmname, vmname, imagename, imagename, vmimage.OSStateGeneralized, vmimage.CaptureParameters{})
}); err != nil {
t.Error(err)
}
im := GetUserVMImage(t, client, imagename)
t.Logf("Found image: %+v", im)
newvmname := GenerateName()
role = NewVMConfiguration(newvmname, "Standard_D3")
ConfigureDeploymentFromUserVMImage(&role, im.Name)
ConfigureForLinux(&role, newvmname, "azureuser", GeneratePassword())
ConfigureWithPublicSSH(&role)
t.Logf("Deploying new VM from freshly captured VM image: %s", newvmname)
if err := Await(client, func() (management.OperationID, error) {
return vmc.CreateDeployment(role, vmname, vm.CreateDeploymentOptions{})
}); err != nil {
t.Error(err)
}
deleteHostedService(t, client, vmname)
}
func TestDeployFromPublishedVmImage(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
im := GetVMImage(t, client, func(im vmimage.VMImage) bool {
return im.Name ==
"fb83b3509582419d99629ce476bcb5c8__SQL-Server-2014-RTM-12.0.2430.0-OLTP-ENU-Win2012R2-cy14su11"
})
role := NewVMConfiguration(vmname, "Standard_D4")
ConfigureDeploymentFromPublishedVMImage(&role, im.Name,
fmt.Sprintf("http://%s.blob.core.windows.net/%s", sa.ServiceName, vmname), false)
ConfigureForWindows(&role, vmname, "azureuser", GeneratePassword(), true, "")
ConfigureWithPublicSSH(&role)
testRoleConfiguration(t, client, role, location)
}
func TestRoleStateOperations(t *testing.T) {
client := testutils.GetTestClient(t)
vmname := GenerateName()
sa := GetTestStorageAccount(t, client)
location := sa.StorageServiceProperties.Location
role := NewVMConfiguration(vmname, "Standard_D3")
ConfigureDeploymentFromPlatformImage(&role,
GetLinuxTestImage(t, client).Name,
fmt.Sprintf("http://%s.blob.core.windows.net/sdktest/%s.vhd", sa.ServiceName, vmname),
GenerateName())
ConfigureForLinux(&role, "myvm", "azureuser", GeneratePassword())
createRoleConfiguration(t, client, role, location)
vmc := vm.NewClient(client)
if err := Await(client, func() (management.OperationID, error) {
return vmc.ShutdownRole(vmname, vmname, vmname, vm.PostShutdownActionStopped)
}); err != nil {
t.Error(err)
}
if err := Await(client, func() (management.OperationID, error) {
return vmc.StartRole(vmname, vmname, vmname)
}); err != nil {
t.Error(err)
}
if err := Await(client, func() (management.OperationID, error) {
return vmc.RestartRole(vmname, vmname, vmname)
}); err != nil {
t.Error(err)
}
deleteHostedService(t, client, vmname)
}
func testRoleConfiguration(t *testing.T, client management.Client, role vm.Role, location string) {
createRoleConfiguration(t, client, role, location)
deleteHostedService(t, client, role.RoleName)
}
func createRoleConfiguration(t *testing.T, client management.Client, role vm.Role, location string) {
vmc := vm.NewClient(client)
hsc := hostedservice.NewClient(client)
vmname := role.RoleName
if err := hsc.CreateHostedService(hostedservice.CreateHostedServiceParameters{
ServiceName: vmname, Location: location,
Label: base64.StdEncoding.EncodeToString([]byte(vmname))}); err != nil {
t.Error(err)
}
if err := Await(client, func() (management.OperationID, error) {
return vmc.CreateDeployment(role, vmname, vm.CreateDeploymentOptions{})
}); err != nil {
t.Error(err)
}
}
func deleteHostedService(t *testing.T, client management.Client, vmname string) {
t.Logf("Deleting hosted service: %s", vmname)
if err := Await(client, func() (management.OperationID, error) {
return hostedservice.NewClient(client).DeleteHostedService(vmname, true)
}); err != nil {
t.Error(err)
}
}
// === utility funcs ===
func GetTestStorageAccount(t *testing.T, client management.Client) storage.StorageServiceResponse {
t.Log("Retrieving storage account")
sc := storage.NewClient(client)
var sa storage.StorageServiceResponse
ssl, err := sc.ListStorageServices()
if err != nil {
t.Fatal(err)
}
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
if len(ssl.StorageServices) == 0 {
t.Log("No storage accounts found, creating a new one")
lc := location.NewClient(client)
ll, err := lc.ListLocations()
if err != nil {
t.Fatal(err)
}
loc := ll.Locations[rnd.Intn(len(ll.Locations))].Name
t.Logf("Location for new storage account: %s", loc)
name := GenerateName()
op, err := sc.CreateStorageService(storage.StorageAccountCreateParameters{
ServiceName: name,
Label: base64.StdEncoding.EncodeToString([]byte(name)),
Location: loc,
AccountType: storage.AccountTypeStandardLRS})
if err != nil {
t.Fatal(err)
}
if err := client.WaitForOperation(op, nil); err != nil {
t.Fatal(err)
}
sa, err = sc.GetStorageService(name)
if err != nil {
t.Fatal(err)
}
} else {
sa = ssl.StorageServices[rnd.Intn(len(ssl.StorageServices))]
}
t.Logf("Selected storage account '%s' in location '%s'",
sa.ServiceName, sa.StorageServiceProperties.Location)
return sa
}
func GetLinuxTestImage(t *testing.T, client management.Client) osimage.OSImage {
return GetOSImage(t, client, func(im osimage.OSImage) bool {
return im.Category == "Public" && im.ImageFamily == "Ubuntu Server 14.04 LTS"
})
}
func GetWindowsTestImage(t *testing.T, client management.Client) osimage.OSImage {
return GetOSImage(t, client, func(im osimage.OSImage) bool {
return im.Category == "Public" && im.ImageFamily == "Windows Server 2012 R2 Datacenter"
})
}
func GetUserOSImage(t *testing.T, client management.Client, name string) osimage.OSImage {
return GetOSImage(t, client, func(im osimage.OSImage) bool {
return im.Category == "User" && im.Name == name
})
}
func GetOSImage(
t *testing.T,
client management.Client,
filter func(osimage.OSImage) bool) osimage.OSImage {
t.Log("Selecting OS image")
osc := osimage.NewClient(client)
allimages, err := osc.ListOSImages()
if err != nil {
t.Fatal(err)
}
filtered := []osimage.OSImage{}
for _, im := range allimages.OSImages {
if filter(im) {
filtered = append(filtered, im)
}
}
if len(filtered) == 0 {
t.Fatal("Filter too restrictive, no images left?")
}
image := filtered[0]
for _, im := range filtered {
if im.PublishedDate > image.PublishedDate {
image = im
}
}
t.Logf("Selecting image '%s'", image.Name)
return image
}
func GetUserVMImage(t *testing.T, client management.Client, name string) vmimage.VMImage {
return GetVMImage(t, client, func(im vmimage.VMImage) bool {
return im.Category == "User" && im.Name == name
})
}
func GetVMImage(
t *testing.T,
client management.Client,
filter func(vmimage.VMImage) bool) vmimage.VMImage {
t.Log("Selecting VM image")
allimages, err := vmimage.NewClient(client).ListVirtualMachineImages(vmimage.ListParameters{})
if err != nil {
t.Fatal(err)
}
filtered := []vmimage.VMImage{}
for _, im := range allimages.VMImages {
if filter(im) {
filtered = append(filtered, im)
}
}
if len(filtered) == 0 {
t.Fatal("Filter too restrictive, no images left?")
}
image := filtered[0]
for _, im := range filtered {
if im.PublishedDate > image.PublishedDate {
image = im
}
}
t.Logf("Selecting image '%s'", image.Name)
return image
}
func GenerateName() string {
from := "1234567890abcdefghijklmnopqrstuvwxyz"
return "sdk" + GenerateString(12, from)
}
func GeneratePassword() string {
pw := GenerateString(20, "1234567890") +
GenerateString(20, "abcdefghijklmnopqrstuvwxyz") +
GenerateString(20, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
i := rnd.Intn(len(pw)-2) + 1
pw = string(append([]uint8(pw[i:]), pw[:i-1]...))
return pw
}
func GenerateString(length int, from string) string {
str := ""
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
for len(str) < length {
str += string(from[rnd.Intn(len(from))])
}
return str
}
type asyncFunc func() (operationId management.OperationID, err error)
func Await(client management.Client, async asyncFunc) error {
requestID, err := async()
if err != nil {
return err
}
return client.WaitForOperation(requestID, nil)
}