Add getting_started tutorial for Gophercloud SDK
Add getting_started tutorial for Gophercloud SDK, code had been tested on a openstack cloud with neutron. Change-Id: Ife8bc23671ddff175a5ff424e08893c746d97482
This commit is contained in:
parent
ed11113c62
commit
7f6e20ae5c
294
firstapp/samples/gophercloud/getting_started.go
Normal file
294
firstapp/samples/gophercloud/getting_started.go
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/rackspace/gophercloud"
|
||||||
|
"github.com/rackspace/gophercloud/openstack"
|
||||||
|
"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/compute/v2/extensions/floatingip"
|
||||||
|
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs"
|
||||||
|
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
|
||||||
|
"github.com/rackspace/gophercloud/openstack/networking/v2/networks"
|
||||||
|
"github.com/rackspace/gophercloud/openstack/networking/v2/extensions/external"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// step-1
|
||||||
|
var authUsername string = "your_auth_username"
|
||||||
|
var authPassword string = "your_auth_password"
|
||||||
|
var authUrl string = "http://controller:5000"
|
||||||
|
var projectName string = "your_project_id"
|
||||||
|
var regionName string = "your_region_name"
|
||||||
|
|
||||||
|
authOpts := gophercloud.AuthOptions{
|
||||||
|
IdentityEndpoint: authUrl,
|
||||||
|
Username: authUsername,
|
||||||
|
Password: authPassword,
|
||||||
|
TenantID: projectName,
|
||||||
|
}
|
||||||
|
provider, _ := openstack.AuthenticatedClient(authOpts)
|
||||||
|
client, _ := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{
|
||||||
|
Region: regionName,
|
||||||
|
})
|
||||||
|
|
||||||
|
// step-2
|
||||||
|
pager := images.ListDetail(client, images.ListOpts{})
|
||||||
|
page, _ := pager.AllPages()
|
||||||
|
imageList, _ := images.ExtractImages(page)
|
||||||
|
fmt.Println(imageList)
|
||||||
|
|
||||||
|
// step-3
|
||||||
|
pager = flavors.ListDetail(client, flavors.ListOpts{})
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
flavorList, _ := flavors.ExtractFlavors(page)
|
||||||
|
fmt.Println(flavorList)
|
||||||
|
|
||||||
|
// step-4
|
||||||
|
imageID := "74e6d1ec-9a08-444c-8518-4f232446386d"
|
||||||
|
image, _ := images.Get(client, imageID).Extract()
|
||||||
|
fmt.Println(image)
|
||||||
|
|
||||||
|
// step-5
|
||||||
|
flavorID := "1"
|
||||||
|
flavor, _ := flavors.Get(client, flavorID).Extract()
|
||||||
|
fmt.Println(flavor)
|
||||||
|
|
||||||
|
// step-6
|
||||||
|
instanceName := "testing"
|
||||||
|
testingInstance, _ := servers.Create(client, servers.CreateOpts{
|
||||||
|
Name: instanceName,
|
||||||
|
ImageRef: imageID,
|
||||||
|
FlavorRef: flavorID,
|
||||||
|
}).Extract()
|
||||||
|
fmt.Println(testingInstance)
|
||||||
|
|
||||||
|
// step-7
|
||||||
|
pager = servers.List(client, servers.ListOpts{})
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
serverList, _ := servers.ExtractServers(page)
|
||||||
|
fmt.Println(serverList)
|
||||||
|
|
||||||
|
// step-8
|
||||||
|
servers.Delete(client, testingInstance.ID)
|
||||||
|
|
||||||
|
// step-9
|
||||||
|
fmt.Println("Checking for existing SSH key pair...")
|
||||||
|
keyPairName := "demokey"
|
||||||
|
pubKeyFile := "~/.ssh/id_rsa.pub"
|
||||||
|
keyPairExists := false
|
||||||
|
|
||||||
|
pager = keypairs.List(client)
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
keypairList, _ := keypairs.ExtractKeyPairs(page)
|
||||||
|
for _, k := range keypairList {
|
||||||
|
if k.Name == keyPairName {
|
||||||
|
keyPairExists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if keyPairExists {
|
||||||
|
fmt.Println("Keypair " + keyPairName + " already exists. Skipping import.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("adding keypair...")
|
||||||
|
bs, _ := ioutil.ReadFile(pubKeyFile)
|
||||||
|
keypairs.Create(client, keypairs.CreateOpts{
|
||||||
|
Name: keyPairName,
|
||||||
|
PublicKey: string(bs),
|
||||||
|
}).Extract()
|
||||||
|
}
|
||||||
|
|
||||||
|
pager = keypairs.List(client)
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
keypairList, _ = keypairs.ExtractKeyPairs(page)
|
||||||
|
fmt.Println(keypairList)
|
||||||
|
|
||||||
|
// step-10
|
||||||
|
fmt.Println("Checking for existing security group...")
|
||||||
|
var allInOneSecurityGroup secgroups.SecurityGroup
|
||||||
|
securityGroupName := "all-in-one"
|
||||||
|
securityGroupExists := false
|
||||||
|
|
||||||
|
pager = secgroups.List(client)
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
secgroupList, _ := secgroups.ExtractSecurityGroups(page)
|
||||||
|
for _, secGroup := range secgroupList {
|
||||||
|
if secGroup.Name == securityGroupName {
|
||||||
|
allInOneSecurityGroup = secGroup
|
||||||
|
securityGroupExists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if securityGroupExists {
|
||||||
|
fmt.Println("Security Group " + allInOneSecurityGroup.Name + " already exists. Skipping creation.")
|
||||||
|
} else {
|
||||||
|
allInOneSecurityGroup, _ := secgroups.Create(client, secgroups.CreateOpts{
|
||||||
|
Name: securityGroupName,
|
||||||
|
Description: "network access for all-in-one application.",
|
||||||
|
}).Extract()
|
||||||
|
secgroups.CreateRule(client, secgroups.CreateRuleOpts{
|
||||||
|
ParentGroupID: allInOneSecurityGroup.ID,
|
||||||
|
FromPort: 80,
|
||||||
|
ToPort: 80,
|
||||||
|
IPProtocol: "TCP",
|
||||||
|
CIDR: "0.0.0.0/0",
|
||||||
|
}).Extract()
|
||||||
|
secgroups.CreateRule(client, secgroups.CreateRuleOpts{
|
||||||
|
ParentGroupID: allInOneSecurityGroup.ID,
|
||||||
|
FromPort: 22,
|
||||||
|
ToPort: 22,
|
||||||
|
IPProtocol: "TCP",
|
||||||
|
CIDR: "0.0.0.0/0",
|
||||||
|
}).Extract()
|
||||||
|
}
|
||||||
|
|
||||||
|
pager = secgroups.List(client)
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
secgroupList, _ = secgroups.ExtractSecurityGroups(page)
|
||||||
|
fmt.Println(secgroupList)
|
||||||
|
|
||||||
|
// step-11
|
||||||
|
userData := `#!/usr/bin/env bash
|
||||||
|
curl -L -s https://git.openstack.org/cgit/openstack/faafo/plain/contrib/install.sh | bash -s -- \
|
||||||
|
-i faafo -i messaging -r api -r worker -r demo
|
||||||
|
`
|
||||||
|
|
||||||
|
// step-12
|
||||||
|
fmt.Println("Checking for existing instance...")
|
||||||
|
instanceName = "all-in-one"
|
||||||
|
instanceExists := false
|
||||||
|
|
||||||
|
pager = servers.List(client, servers.ListOpts{})
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
serverList, _ = servers.ExtractServers(page)
|
||||||
|
for _, s := range serverList {
|
||||||
|
if s.Name == instanceName {
|
||||||
|
testingInstance = &s
|
||||||
|
instanceExists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if instanceExists {
|
||||||
|
fmt.Println("Instance " + testingInstance.Name + " already exists. Skipping creation.")
|
||||||
|
} else {
|
||||||
|
opts := servers.CreateOpts{
|
||||||
|
Name: instanceName,
|
||||||
|
ImageRef: image.ID,
|
||||||
|
FlavorRef: flavor.ID,
|
||||||
|
SecurityGroups: []string{securityGroupName},
|
||||||
|
UserData: []byte(userData),
|
||||||
|
}
|
||||||
|
testingInstance, _ = servers.Create(client, keypairs.CreateOptsExt{
|
||||||
|
CreateOptsBuilder: opts,
|
||||||
|
KeyName: keyPairName,
|
||||||
|
}).Extract()
|
||||||
|
}
|
||||||
|
servers.WaitForStatus(client, testingInstance.ID, "ACTIVE", 300)
|
||||||
|
|
||||||
|
pager = servers.List(client, servers.ListOpts{})
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
serverList, _ = servers.ExtractServers(page)
|
||||||
|
fmt.Println(serverList)
|
||||||
|
|
||||||
|
// step-13
|
||||||
|
var privateIP string
|
||||||
|
for t, addrs := range testingInstance.Addresses {
|
||||||
|
if t != "private" || len(privateIP) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs, ok := addrs.([]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
a, ok := addr.(map[string]interface{})
|
||||||
|
if !ok || a["version"].(float64) != 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ip, ok := a["addr"].(string)
|
||||||
|
if ok && len(ip) != 0 {
|
||||||
|
privateIP = ip
|
||||||
|
fmt.Println("Private IP found: " + privateIP)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step-14
|
||||||
|
var publicIP string
|
||||||
|
for t, addrs := range testingInstance.Addresses {
|
||||||
|
if t != "public" || len(publicIP) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs, ok := addrs.([]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
a, ok := addr.(map[string]interface{})
|
||||||
|
if !ok || a["version"].(float64) != 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ip, ok := a["addr"].(string)
|
||||||
|
if ok && len(ip) != 0 {
|
||||||
|
publicIP = ip
|
||||||
|
fmt.Println("Public IP found: " + publicIP)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step-15
|
||||||
|
fmt.Println("Checking for unused Floating IP...")
|
||||||
|
var unusedFloatingIP string
|
||||||
|
pager = floatingip.List(client)
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
floatingIPList, _ := floatingip.ExtractFloatingIPs(page)
|
||||||
|
for _, ip := range floatingIPList {
|
||||||
|
if ip.InstanceID == "" {
|
||||||
|
unusedFloatingIP = ip.IP
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
networkClient, _ := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
|
||||||
|
Region: regionName,
|
||||||
|
})
|
||||||
|
|
||||||
|
pager = networks.List(networkClient, networks.ListOpts{})
|
||||||
|
page, _ = pager.AllPages()
|
||||||
|
poolList, _ := external.ExtractList(page)
|
||||||
|
for _, pool := range poolList {
|
||||||
|
if len(unusedFloatingIP) != 0 || !pool.External {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Println("Allocating new Floating IP from pool: " + pool.Name)
|
||||||
|
f, _ := floatingip.Create(client, floatingip.CreateOpts{Pool: pool.Name}).Extract()
|
||||||
|
unusedFloatingIP = f.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
// step-16
|
||||||
|
if len(publicIP) != 0 {
|
||||||
|
fmt.Println("Instance " + testingInstance.Name + " already has a public ip. Skipping attachment.")
|
||||||
|
} else {
|
||||||
|
floatingip.Associate(client, testingInstance.ID, unusedFloatingIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
// step-17
|
||||||
|
var actualIPAddress string
|
||||||
|
if len(publicIP) != 0 {
|
||||||
|
actualIPAddress = publicIP
|
||||||
|
} else if len(unusedFloatingIP) != 0 {
|
||||||
|
actualIPAddress = unusedFloatingIP
|
||||||
|
} else {
|
||||||
|
actualIPAddress = privateIP
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("The Fractals app will be deployed to http://" + actualIPAddress)
|
||||||
|
}
|
@ -96,6 +96,11 @@ and toolkits with the OpenStack cloud:
|
|||||||
- A .NET-based library.
|
- A .NET-based library.
|
||||||
Use it to write C++ or C# code for Microsoft applications.
|
Use it to write C++ or C# code for Microsoft applications.
|
||||||
- https://www.nuget.org/packages/openstack.net
|
- https://www.nuget.org/packages/openstack.net
|
||||||
|
* - Go
|
||||||
|
- `gophercloud <https://github.com/rackspace/gophercloud>`_
|
||||||
|
- A go-based SDK.
|
||||||
|
Use it with multiple clouds.
|
||||||
|
- http://gophercloud.io/
|
||||||
|
|
||||||
For a list of available SDKs, see `Software Development Kits <https://wiki.openstack.org/wiki/SDKs>`_.
|
For a list of available SDKs, see `Software Development Kits <https://wiki.openstack.org/wiki/SDKs>`_.
|
||||||
|
|
||||||
@ -181,6 +186,11 @@ To interact with the cloud, you must also have
|
|||||||
|
|
||||||
.. note:: Before proceeding, install the latest version of shade.
|
.. note:: Before proceeding, install the latest version of shade.
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
`a recent version of gophercloud installed <https://godoc.org/github.com/rackspace/gophercloud>`_
|
||||||
|
|
||||||
|
|
||||||
Obtain the following information from your cloud provider:
|
Obtain the following information from your cloud provider:
|
||||||
|
|
||||||
* auth URL
|
* auth URL
|
||||||
@ -307,6 +317,18 @@ to run code snippets in your language of choice.
|
|||||||
of the following API calls please double-check your
|
of the following API calls please double-check your
|
||||||
credentials.
|
credentials.
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
To try it, add the following code to go file
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-1
|
||||||
|
:end-before: step-2
|
||||||
|
|
||||||
|
.. note:: The client object accesses the Compute v2.0 service,
|
||||||
|
so that version is in this tutorial.
|
||||||
|
|
||||||
Flavors and images
|
Flavors and images
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -425,6 +447,20 @@ To list the images that are available in your cloud, run some API calls:
|
|||||||
openstack.image.v1.image.Image(attrs={u'name': u'ubuntu-14.04', u'container_format': u'bare', u'disk_format': u'qcow2', u'checksum': u'6d8f1c8cf05e1fbdc8b543fda1a9fa7f', u'id': u'cb6b7936-d2c5-4901-8678-c88b3a6ed84c', u'size': 258540032}, loaded=True)
|
openstack.image.v1.image.Image(attrs={u'name': u'ubuntu-14.04', u'container_format': u'bare', u'disk_format': u'qcow2', u'checksum': u'6d8f1c8cf05e1fbdc8b543fda1a9fa7f', u'id': u'cb6b7936-d2c5-4901-8678-c88b3a6ed84c', u'size': 258540032}, loaded=True)
|
||||||
...
|
...
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-2
|
||||||
|
:end-before: step-3
|
||||||
|
|
||||||
|
This code returns output like this:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
[{74e6d1ec-9a08-444c-8518-4f232446386d 2016-02-01T07:20:31Z 0 0 cirros-0.3.4-x86_64-uec 100 ACTIVE 2016-02-01T07:20:32Z}
|
||||||
|
{f70b7fb0-348a-4519-b358-0f239dc64dc5 2016-02-01T07:20:30Z 0 0 cirros-0.3.4-x86_64-uec-ramdisk 100 ACTIVE 2016-02-01T07:20:31Z}
|
||||||
|
{e92f5e17-60d2-4cb5-b893-d605b136afab 2016-02-01T07:20:29Z 0 0 cirros-0.3.4-x86_64-uec-kernel 100 ACTIVE 2016-02-01T07:20:30Z}]
|
||||||
|
|
||||||
You can also get information about available flavors:
|
You can also get information about available flavors:
|
||||||
|
|
||||||
@ -545,6 +581,22 @@ You can also get information about available flavors:
|
|||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-3
|
||||||
|
:end-before: step-4
|
||||||
|
|
||||||
|
This code returns output like this:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
[{1 1 512 m1.tiny 1 0 1}
|
||||||
|
{2 20 2048 m1.small 1 0 1}
|
||||||
|
{3 40 4096 m1.medium 1 0 2}
|
||||||
|
...
|
||||||
|
{84 0 128 m1.micro 1 0 1}]
|
||||||
|
|
||||||
Your images and flavors will be different, of course.
|
Your images and flavors will be different, of course.
|
||||||
|
|
||||||
@ -656,6 +708,19 @@ image that you picked in the previous section:
|
|||||||
|
|
||||||
openstack.image.v1.image.Image(attrs={u'name': u'ubuntu-14.04', u'container_format': u'bare', u'disk_format': u'qcow2', u'checksum': u'6d8f1c8cf05e1fbdc8b543fda1a9fa7f', u'id': u'cb6b7936-d2c5-4901-8678-c88b3a6ed84c', u'size': 258540032}, loaded=True)
|
openstack.image.v1.image.Image(attrs={u'name': u'ubuntu-14.04', u'container_format': u'bare', u'disk_format': u'qcow2', u'checksum': u'6d8f1c8cf05e1fbdc8b543fda1a9fa7f', u'id': u'cb6b7936-d2c5-4901-8678-c88b3a6ed84c', u'size': 258540032}, loaded=True)
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-4
|
||||||
|
:end-before: step-5
|
||||||
|
|
||||||
|
You should see output like this:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
&{74e6d1ec-9a08-444c-8518-4f232446386d 2016-02-01T07:20:31Z 0 0 cirros-0.3.4-x86_64-uec 100 ACTIVE 2016-02-01T07:20:32Z}
|
||||||
|
|
||||||
Next, tell the script which flavor you want to use:
|
Next, tell the script which flavor you want to use:
|
||||||
|
|
||||||
.. only:: fog
|
.. only:: fog
|
||||||
@ -755,6 +820,19 @@ Next, tell the script which flavor you want to use:
|
|||||||
|
|
||||||
openstack.compute.v2.flavor.Flavor(attrs={u'name': u'm1.small', u'links': [{u'href': u'http://controller:8774/v2/96ff6aa79e60423d9848b70d5475c415/flavors/2', u'rel': u'self'}, {u'href': u'http://controller:8774/96ff6aa79e60423d9848b70d5475c415/flavors/2', u'rel': u'bookmark'}], u'ram': 2048, u'OS-FLV-DISABLED:disabled': False, u'vcpus': 1, u'swap': u'', u'os-flavor-access:is_public': True, u'rxtx_factor': 1.0, u'OS-FLV-EXT-DATA:ephemeral': 0, u'disk': 20, 'id': u'2'}, loaded=True)
|
openstack.compute.v2.flavor.Flavor(attrs={u'name': u'm1.small', u'links': [{u'href': u'http://controller:8774/v2/96ff6aa79e60423d9848b70d5475c415/flavors/2', u'rel': u'self'}, {u'href': u'http://controller:8774/96ff6aa79e60423d9848b70d5475c415/flavors/2', u'rel': u'bookmark'}], u'ram': 2048, u'OS-FLV-DISABLED:disabled': False, u'vcpus': 1, u'swap': u'', u'os-flavor-access:is_public': True, u'rxtx_factor': 1.0, u'OS-FLV-EXT-DATA:ephemeral': 0, u'disk': 20, 'id': u'2'}, loaded=True)
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-5
|
||||||
|
:end-before: step-6
|
||||||
|
|
||||||
|
You should see output like this:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
&{1 1 512 m1.tiny 1 0 1}
|
||||||
|
|
||||||
Now, you can launch the instance.
|
Now, you can launch the instance.
|
||||||
|
|
||||||
Launch an instance
|
Launch an instance
|
||||||
@ -836,6 +914,19 @@ Create the instance.
|
|||||||
:start-after: step-6
|
:start-after: step-6
|
||||||
:end-before: step-7
|
:end-before: step-7
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-6
|
||||||
|
:end-before: step-7
|
||||||
|
|
||||||
|
You should see output like this:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
&{739dd964-ae88-461d-9746-f8f1139d20f6 0 map[] map[] map[] map[] ... RPUkTFM8fynn [map[name:default]]}
|
||||||
|
|
||||||
If you list existing instances:
|
If you list existing instances:
|
||||||
|
|
||||||
.. only:: fog
|
.. only:: fog
|
||||||
@ -878,6 +969,13 @@ If you list existing instances:
|
|||||||
:start-after: step-7
|
:start-after: step-7
|
||||||
:end-before: step-8
|
:end-before: step-8
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-7
|
||||||
|
:end-before: step-8
|
||||||
|
|
||||||
The new instance appears.
|
The new instance appears.
|
||||||
|
|
||||||
.. only:: libcloud
|
.. only:: libcloud
|
||||||
@ -982,6 +1080,14 @@ The new instance appears.
|
|||||||
updated: '2015-07-20T20:31:10Z'
|
updated: '2015-07-20T20:31:10Z'
|
||||||
user_id: bfd3dbf1c8a242cd90884408de547bb9
|
user_id: bfd3dbf1c8a242cd90884408de547bb9
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
[...
|
||||||
|
{739dd964-ae88-461d-9746-f8f1139d20f6 061fdb617b6c4bdf8694bf5b0d8eefdd bb210009e42c4b509ba75893a757c8e5 testing 2016-02-16T07:16:52Z 2016-02-16T07:16:52Z 2d2f4bba90498fd46c72e7d019dde9189c36637b73e71e1e652d75db BUILD 0 ... [map[name:default]]}
|
||||||
|
...]
|
||||||
|
|
||||||
Before you continue, you must do one more thing.
|
Before you continue, you must do one more thing.
|
||||||
|
|
||||||
Destroy an instance
|
Destroy an instance
|
||||||
@ -1029,6 +1135,13 @@ cost money. To avoid unexpected expenses, destroy cloud resources.
|
|||||||
:start-after: step-8
|
:start-after: step-8
|
||||||
:end-before: step-9
|
:end-before: step-9
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-8
|
||||||
|
:end-before: step-9
|
||||||
|
|
||||||
If you list the instances again, the instance disappears.
|
If you list the instances again, the instance disappears.
|
||||||
|
|
||||||
Leave your shell open to use it for another instance deployment in this
|
Leave your shell open to use it for another instance deployment in this
|
||||||
@ -1101,6 +1214,13 @@ your public SSH key file.
|
|||||||
|
|
||||||
openstack.compute.v2.keypair.Keypair(attrs={u'public_key': u'ssh-rsa ABAAABAQCyyzkyaPf.....', u'name': u'demokey', u'fingerprint': aa:bb:cc:... '}, loaded=True)
|
openstack.compute.v2.keypair.Keypair(attrs={u'public_key': u'ssh-rsa ABAAABAQCyyzkyaPf.....', u'name': u'demokey', u'fingerprint': aa:bb:cc:... '}, loaded=True)
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-9
|
||||||
|
:end-before: step-10
|
||||||
|
|
||||||
* Network access. By default, OpenStack filters all traffic. You must create
|
* Network access. By default, OpenStack filters all traffic. You must create
|
||||||
a security group and apply it to your instance. The security group allows HTTP
|
a security group and apply it to your instance. The security group allows HTTP
|
||||||
and SSH access. We will go into more detail in :doc:`/introduction`.
|
and SSH access. We will go into more detail in :doc:`/introduction`.
|
||||||
@ -1136,6 +1256,13 @@ your public SSH key file.
|
|||||||
:start-after: step-10
|
:start-after: step-10
|
||||||
:end-before: step-11
|
:end-before: step-11
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-10
|
||||||
|
:end-before: step-11
|
||||||
|
|
||||||
* Userdata. During instance creation, you can provide userdata to OpenStack to
|
* Userdata. During instance creation, you can provide userdata to OpenStack to
|
||||||
configure instances after they boot. The cloud-init service applies the
|
configure instances after they boot. The cloud-init service applies the
|
||||||
user data to an instance. You must pre-install the cloud-init service on your
|
user data to an instance. You must pre-install the cloud-init service on your
|
||||||
@ -1174,6 +1301,13 @@ your public SSH key file.
|
|||||||
:start-after: step-11
|
:start-after: step-11
|
||||||
:end-before: step-12
|
:end-before: step-12
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-11
|
||||||
|
:end-before: step-12
|
||||||
|
|
||||||
Now, you can boot and configure the instance.
|
Now, you can boot and configure the instance.
|
||||||
|
|
||||||
Boot and configure an instance
|
Boot and configure an instance
|
||||||
@ -1215,6 +1349,13 @@ After you request the instance, wait for it to build.
|
|||||||
:start-after: step-12
|
:start-after: step-12
|
||||||
:end-before: step-13
|
:end-before: step-13
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-12
|
||||||
|
:end-before: step-13
|
||||||
|
|
||||||
When the instance boots, the `ex_userdata` variable value instructs the
|
When the instance boots, the `ex_userdata` variable value instructs the
|
||||||
instance to deploy the Fractals application.
|
instance to deploy the Fractals application.
|
||||||
|
|
||||||
@ -1339,6 +1480,45 @@ instance.
|
|||||||
:start-after: step-14
|
:start-after: step-14
|
||||||
:end-before: step-15
|
:end-before: step-15
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
To see whether a private IP address is assigned to your instance:
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-13
|
||||||
|
:end-before: step-14
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
If one is assigned, users can use this address to access the instance on
|
||||||
|
some OpenStack clouds.
|
||||||
|
|
||||||
|
To determine whether a public IP address is assigned to your instance:
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-14
|
||||||
|
:end-before: step-15
|
||||||
|
|
||||||
|
If one is assigned, users can use this address to access the instance.
|
||||||
|
|
||||||
|
To create a floating IP address to use with your instance:
|
||||||
|
|
||||||
|
Use network service client to select the first floating IP address pool.
|
||||||
|
Allocate this pool to your project and use it to get a floating IP address.
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-15
|
||||||
|
:end-before: step-16
|
||||||
|
|
||||||
|
Attach the floating IP address to the instance:
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-16
|
||||||
|
:end-before: step-17
|
||||||
|
|
||||||
Run the script to start the deployment.
|
Run the script to start the deployment.
|
||||||
|
|
||||||
@ -1376,6 +1556,12 @@ interface at the following link.
|
|||||||
.. literalinclude:: ../samples/openstacksdk/getting_started.py
|
.. literalinclude:: ../samples/openstacksdk/getting_started.py
|
||||||
:start-after: step-15
|
:start-after: step-15
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
:start-after: step-17
|
||||||
|
|
||||||
.. note:: If you do not use floating IP addresses, substitute another IP
|
.. note:: If you do not use floating IP addresses, substitute another IP
|
||||||
address, as appropriate.
|
address, as appropriate.
|
||||||
|
|
||||||
@ -1442,3 +1628,8 @@ information, the flavor ID, and image ID.
|
|||||||
|
|
||||||
.. literalinclude:: ../samples/openstacksdk/getting_started.py
|
.. literalinclude:: ../samples/openstacksdk/getting_started.py
|
||||||
:language: python
|
:language: python
|
||||||
|
|
||||||
|
.. only:: gophercloud
|
||||||
|
|
||||||
|
.. literalinclude:: ../samples/gophercloud/getting_started.go
|
||||||
|
:language: go
|
||||||
|
@ -9,7 +9,7 @@ for tag in libcloud; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Draft documents
|
# Draft documents
|
||||||
for tag in dotnet fog openstacksdk pkgcloud shade jclouds; do
|
for tag in dotnet fog openstacksdk pkgcloud shade jclouds gophercloud; do
|
||||||
tools/build-rst.sh firstapp \
|
tools/build-rst.sh firstapp \
|
||||||
--tag ${tag} --target "api-ref/draft/firstapp-${tag}"
|
--tag ${tag} --target "api-ref/draft/firstapp-${tag}"
|
||||||
done
|
done
|
||||||
|
3
tox.ini
3
tox.ini
@ -161,6 +161,9 @@ commands = sphinx-build -E -W -t libcloud firstapp/source firstapp/build/html
|
|||||||
[testenv:firstapp-shade]
|
[testenv:firstapp-shade]
|
||||||
commands = sphinx-build -E -W -t shade firstapp/source firstapp/build-shade/html
|
commands = sphinx-build -E -W -t shade firstapp/source firstapp/build-shade/html
|
||||||
|
|
||||||
|
[testenv:firstapp-gophercloud]
|
||||||
|
commands = sphinx-build -E -W -t gophercloud firstapp/source firstapp/build-gophercloud/html
|
||||||
|
|
||||||
[testenv:api-quick-start]
|
[testenv:api-quick-start]
|
||||||
commands =
|
commands =
|
||||||
{toxinidir}/tools/build-api-quick-start.sh
|
{toxinidir}/tools/build-api-quick-start.sh
|
||||||
|
Loading…
Reference in New Issue
Block a user