Created
September 9, 2016 15:54
-
-
Save spareslant/4774569f41c00c41beab4df6c72f29da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/rand" | |
"errors" | |
"flag" | |
"fmt" | |
"github.com/rackspace/gophercloud" | |
"github.com/rackspace/gophercloud/openstack" | |
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip" | |
"github.com/rackspace/gophercloud/openstack/compute/v2/flavors" | |
"github.com/rackspace/gophercloud/openstack/compute/v2/images" | |
"github.com/rackspace/gophercloud/openstack/compute/v2/servers" | |
"github.com/rackspace/gophercloud/openstack/networking/v2/networks" | |
"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 generateRandomString() string { | |
b := make([]byte, 8) | |
_, err := rand.Read(b) | |
checkErrorAndExit(err) | |
name := fmt.Sprintf("%X", b[0:4]) | |
return name | |
} | |
func getFreeFloatingIP(client *gophercloud.ServiceClient) (*string, error) { | |
pager := floatingip.List(client) | |
singlePage, err := pager.AllPages() | |
checkErrorAndExit(err) | |
floatingIPList, err := floatingip.ExtractFloatingIPs(singlePage) | |
checkErrorAndExit(err) | |
for _, floatingIP := range floatingIPList { | |
// Check ip floatingIP is assigned to any Instance. | |
if len(floatingIP.InstanceID) > 0 { | |
//Do nothing | |
} else { | |
return &floatingIP.IP, nil | |
} | |
} | |
return nil, errors.New("ERROR: Free FloatingIP not available.") | |
} | |
func assignFloatingIP(client *gophercloud.ServiceClient, id string, ip string) { | |
fmt.Printf("Attaching floating IP with first VM. It can take a few seconds.\n") | |
opts := floatingip.AssociateOpts{ServerID: id, FloatingIP: ip} | |
for { | |
server, err := servers.Get(client, id).Extract() | |
checkErrorAndExit(err) | |
if server.Status == "ACTIVE" { | |
result := floatingip.AssociateInstance(client, opts) | |
if result.Err != nil { | |
fmt.Println(result.Err) | |
} else { | |
fmt.Println("Floating IP assigned successfully.") | |
} | |
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: ") | |
} | |
authOpts, err := openstack.AuthOptionsFromEnv() | |
checkErrorAndExit(err) | |
provider, err := openstack.AuthenticatedClient(authOpts) | |
checkErrorAndExit(err) | |
otherOpts := gophercloud.EndpointOpts{Region: *region} | |
client, err := openstack.NewComputeV2(provider, otherOpts) | |
imageID, err := images.IDFromName(client, *image) | |
checkErrorAndExit(err) | |
flavorID, err := flavors.IDFromName(client, *flavor) | |
checkErrorAndExit(err) | |
netClient, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{Name: "neutron", Region: *region}) | |
checkErrorAndExit(err) | |
networkID, err := networks.IDFromName(netClient, *network) | |
checkErrorAndExit(err) | |
/* This code is not needed. | |
securityGroupID, err := getSecurityGroupID(client, *securityGroup) | |
checkErrorAndExit(err) | |
fmt.Println(*securityGroupID) | |
*/ | |
network1 := servers.Network{UUID: networkID, FixedIP: "", Port: ""} | |
allNetworks := []servers.Network{network1} | |
noOfInstances, err := strconv.Atoi(*total) | |
checkErrorAndExit(err) | |
for i := 1; i <= noOfInstances; i++ { | |
vmName := *hostNamePrefix + strconv.Itoa(i) | |
serverCreateOpts := servers.CreateOpts{Name: vmName, | |
FlavorRef: flavorID, | |
ImageRef: imageID, | |
Networks: allNetworks, | |
UserData: []byte{}, | |
SecurityGroups: []string{*securityGroup}} | |
_, err := servers.Create(client, serverCreateOpts).Extract() | |
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 := servers.IDFromName(client, *hostNamePrefix+strconv.Itoa(1)) | |
checkErrorAndExit(err) | |
fmt.Printf("Obtaining free floating IP: ") | |
floatingIP, err := getFreeFloatingIP(client) | |
checkErrorAndExit(err) | |
fmt.Printf("%s found.\n", *floatingIP) | |
assignFloatingIP(client, vmID, *floatingIP) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment