Skip to content

Instantly share code, notes, and snippets.

@spareslant
Created September 9, 2016 15:53
Show Gist options
  • Save spareslant/b2d79bbdee350d8a82687045256dfb67 to your computer and use it in GitHub Desktop.
Save spareslant/b2d79bbdee350d8a82687045256dfb67 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/rand"
"errors"
"flag"
"fmt"
"gopkg.in/goose.v1/client"
"gopkg.in/goose.v1/glance"
"gopkg.in/goose.v1/identity"
"gopkg.in/goose.v1/nova"
"log"
"os"
"strconv"
"time"
)
func checkErrorAndExit(err error) {
if err != nil {
fmt.Printf("Error: %v\n", err.Error())
os.Exit(3)
}
}
func checkErrorAndContinue(err error) {
if err != nil {
fmt.Printf("Error: %v\n", err.Error())
}
}
func getImageID(clientHandle client.Client, name string) (*string, error) {
c1 := glance.New(clientHandle)
entities, _ := c1.ListImages()
for _, entity := range entities {
if entity.Name == name {
return &entity.Id, nil
}
}
return nil, errors.New("ERROR: Image " + name + " not found. Does it exist?")
}
func getFlavorID(clientHandle client.Client, name string) (*string, error) {
c1 := nova.New(clientHandle)
entities, _ := c1.ListFlavors()
for _, entity := range entities {
if entity.Name == name {
return &entity.Id, nil
}
}
return nil, errors.New("ERROR: Flavor " + name + " not found. Does it exist?")
}
func getNetworkID(clientHandle client.Client, name string) (*string, error) {
c1 := nova.New(clientHandle)
entities, _ := c1.ListNetworks()
for _, entity := range entities {
if entity.Label == name {
return &entity.Id, nil
}
}
return nil, errors.New("ERROR: Network " + name + " not found. Does it exist?")
}
func getSecurityGroupID(clientHandle client.Client, name string) (*string, error) {
c1 := nova.New(clientHandle)
entities, _ := c1.ListSecurityGroups()
for _, entity := range entities {
if entity.Name == name {
return &entity.Id, nil
}
}
return nil, errors.New("ERROR: SecurityGroup " + name + " not found. Does it exist?")
}
func generateRandomString() string {
b := make([]byte, 8)
_, err := rand.Read(b)
checkErrorAndExit(err)
name := fmt.Sprintf("%X", b[0:4])
return name
}
func getFreeFloatingIP(clientHandle client.Client) (*string, error) {
c1 := nova.New(clientHandle)
entities, _ := c1.ListFloatingIPs()
for _, entity := range entities {
// Make sure this floatingIP is not assigned to a VM already
if entity.InstanceId == nil {
return &entity.IP, nil
}
}
return nil, errors.New("ERROR: FloatingIP not available. Has it been allocated to project?")
}
func getVmIdfromName(clientHandle client.Client, vmName string) (*string, error) {
filter := nova.NewFilter()
filter.Set(nova.FilterServer, vmName)
filterHandle := nova.New(clientHandle)
serverList, err := filterHandle.ListServers(filter)
checkErrorAndContinue(err)
for _, server := range serverList {
if server.Name == vmName {
return &server.Id, nil
}
}
return nil, errors.New("ERROR: Instance " + vmName + " not found. Does it exist?")
}
func assignFloatingIP(clientHandle client.Client, id string, ip string) {
fmt.Println("Assigning Floating IP to first instance. Can take a few seconds.")
serverHandle := nova.New(clientHandle)
for {
details, err := serverHandle.GetServer(id)
checkErrorAndContinue(err)
if details.Status == "ACTIVE" {
err := serverHandle.AddServerFloatingIP(id, ip)
checkErrorAndExit(err)
fmt.Println("done.")
os.Exit(0)
}
time.Sleep(1000 * time.Millisecond)
//fmt.Println(details.Status)
}
}
func main() {
user := flag.String("user", "admin", "OS Username")
pass := flag.String("password", "acf0d596fbb44b1d", "Password")
authUrl := flag.String("authurl", "http://10.0.2.15:5000/v2.0", "AUTH URL")
tenant := flag.String("tenant", "admin", "Tenant Name")
region := flag.String("region", "RegionOne", "Region for VM")
defaultRun := flag.Bool("runwithdefaultvalues", false, "Use this flag to use default values")
image := flag.String("image", "cirros", "Image to be used")
flavor := flag.String("flavor", "m1.tiny", "Size of VM")
network := flag.String("network", "private", "Network for VM")
securityGroup := flag.String("securitygroup", "default", "Security Group for VM")
hostNamePrefix := flag.String("hostnameprefix", generateRandomString(), "Hostname Prefix. default: randomly generated.")
total := flag.String("total", "5", "Total number of instances")
flag.Parse()
os.Setenv("OS_USERNAME", *user)
os.Setenv("OS_PASSWORD", *pass)
os.Setenv("OS_AUTH_URL", *authUrl)
os.Setenv("OS_TENANT_NAME", *tenant)
os.Setenv("OS_REGION_NAME", *region)
if flag.NFlag() == 0 {
flag.PrintDefaults()
os.Exit(1)
} else if *defaultRun == true {
fmt.Println("Creating VMs: ")
} else {
fmt.Println("Creating VMs: ")
}
creds := identity.CredentialsFromEnv()
logger := log.New(os.Stdout, "INFO: ", log.Lshortfile)
clientHandle := client.NewClient(creds, identity.AuthUserPass, logger)
imageID, err := getImageID(clientHandle, *image)
checkErrorAndExit(err)
flavorID, err := getFlavorID(clientHandle, *flavor)
checkErrorAndExit(err)
networkID, err := getNetworkID(clientHandle, *network)
checkErrorAndExit(err)
securityGroupID, err := getSecurityGroupID(clientHandle, *securityGroup)
checkErrorAndExit(err)
network1 := nova.ServerNetworks{NetworkId: *networkID, FixedIp: "", PortId: ""}
allNetworks := []nova.ServerNetworks{network1}
securityGroup1 := nova.SecurityGroupName{Name: *securityGroupID}
allSecurityGroups := []nova.SecurityGroupName{securityGroup1}
noOfInstances, err := strconv.Atoi(*total)
checkErrorAndExit(err)
for i := 1; i <= noOfInstances; i++ {
vmName := *hostNamePrefix + strconv.Itoa(i)
vm := nova.RunServerOpts{Name: vmName,
FlavorId: *flavorID,
ImageId: *imageID,
Networks: allNetworks,
UserData: []byte{},
SecurityGroupNames: allSecurityGroups}
vmHandle := nova.New(clientHandle)
_, err := vmHandle.RunServer(vm)
checkErrorAndContinue(err)
fmt.Printf("%s VM creation request sent successfully.\n Details: { flavor=%s, image=%s, network=%s, sec_group=%s }\n", vmName, *flavor, *image, *network, *securityGroup)
fmt.Println("===================================")
}
vmID, err := getVmIdfromName(clientHandle, *hostNamePrefix+strconv.Itoa(1))
checkErrorAndExit(err)
floatingIP, err := getFreeFloatingIP(clientHandle)
checkErrorAndExit(err)
assignFloatingIP(clientHandle, *vmID, *floatingIP)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment