A better create server example

It's much more straight-forward for users to read a create server
example that does everything necessary to create the server
within the body of a single method. In this better example the user
doesn't have to refer to other examples to learn how to create a
server.

Change-Id: Iad7eef7946e93deb735fddcfbe39bbc8b56f507b
This commit is contained in:
Everett Toews 2015-10-30 15:57:38 -05:00
parent 7b0ba7bfbb
commit 6b2cec41d1
10 changed files with 127 additions and 43 deletions

View File

@ -6,13 +6,10 @@ clouds:
username: demo
password: secrete
project_name: demo
hp:
cloud: hp
auth:
username: joe
password: joes-password
project_name: joe-tenant1
region_name: region-b.geo-1
example:
image_name: fedora-20.x86_64
flavor_name: m1.small
network_name: private
rackspace:
cloud: rackspace
auth:

View File

@ -56,8 +56,12 @@ Create Server
-------------
At minimum, a server requires a name, an image, a flavor, and a network on
creation. Once you've discovered these attributes by listing them as above,
you can create a server.
creation. You can discover the names and IDs of these attributes by listing
them as above and then using the find methods to get the appropriate
resources.
Ideally you'll also create a server using a public/private keypair so you can
login to that server with the private key.
Servers take time to boot so we call ``wait_for_server`` to wait
for it to become active.

View File

@ -18,8 +18,7 @@ To create a connection you need a :class:`~openstack.profile.Profile` and a
:class:`~openstack.connection.Connection`.
.. literalinclude:: ../examples/connect.py
:language: python
:lines: 32-44
:pyobject: create_connection
The :class:`~openstack.profile.Profile` sets your preferences for each
service. You will pass it the region of the OpenStack cloud that this
@ -27,9 +26,9 @@ connection will use.
The :class:`~openstack.connection.Connection` is a context for a connection
to an OpenStack cloud. You will primarily use it to set the
:class:`~openstack.profile.Profile` and authentication information with the
``auth_args`` parameter. You can also set the ``user_agent`` to something that
describes your application (e.g. ``my-web-app/1.3.4``).
:class:`~openstack.profile.Profile` and authentication information. You can
also set the ``user_agent`` to something that describes your application
(e.g. ``my-web-app/1.3.4``).
Full example at `connect.py <http://git.openstack.org/cgit/openstack/python-openstacksdk/tree/examples/connect.py>`_

View File

@ -19,13 +19,12 @@ Default Location
****************
To create a connection from a file you need a YAML file to contain the
configuration and the :py:func:`~openstack.connection.from_config`
function.
configuration.
.. literalinclude:: ../../contributors/clouds.yaml
:language: yaml
To look for a configuration file called ``clouds.yaml`` in the default
To use a configuration file called ``clouds.yaml`` in one of the default
locations:
* Current Directory
@ -36,15 +35,17 @@ call :py:func:`~openstack.connection.from_config` with an object that has
the name of the cloud configuration to use.
.. literalinclude:: ../examples/connect.py
:language: python
:lines: 23-30
:pyobject: Opts
.. literalinclude:: ../examples/connect.py
:pyobject: create_connection_from_config
.. note:: To enable logging, set ``debug=True`` in the ``Opts`` object.
User Defined Location
*********************
To look for a configuration file in a user defined location set the
To use a configuration file in a user defined location set the
environment variable ``OS_CLIENT_CONFIG_FILE`` to the
absolute path of a file.::
@ -54,8 +55,10 @@ and call :py:func:`~openstack.connection.from_config` with an object that has
the name of the cloud configuration to use.
.. literalinclude:: ../examples/connect.py
:language: python
:lines: 23-30
:pyobject: Opts
.. literalinclude:: ../examples/connect.py
:pyobject: create_connection_from_config
.. note:: To enable logging, set ``debug=True`` in the ``Opts`` object.

View File

@ -10,6 +10,14 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
from examples.connect import FLAVOR_NAME
from examples.connect import IMAGE_NAME
from examples.connect import KEYPAIR_NAME
from examples.connect import NETWORK_NAME
from examples.connect import PRIVATE_KEYPAIR_FILE
"""
Create resources with the Compute service.
@ -17,12 +25,27 @@ For a full guide see TODO(etoews):link to docs on developer.openstack.org
"""
def create_server(conn, name, image, flavor, network):
def create_server(conn):
print("Create Server:")
server = conn.compute.create_server(name=name, image=image,
flavor=flavor,
networks=[{"uuid": network.id}])
conn.compute.wait_for_server(server)
image = conn.compute.find_image(IMAGE_NAME)
flavor = conn.compute.find_flavor(FLAVOR_NAME)
network = conn.network.find_network(NETWORK_NAME)
print(server)
if not conn.compute.find_keypair(KEYPAIR_NAME):
keypair = conn.compute.create_keypair(name=KEYPAIR_NAME)
with open(PRIVATE_KEYPAIR_FILE, 'w') as f:
f.write("%s" % keypair.private_key)
os.chmod(PRIVATE_KEYPAIR_FILE, 0o400)
server = conn.compute.create_server(
name='openstacksdk-example', image=image, flavor=flavor,
networks=[{"uuid": network.id}], key_name=KEYPAIR_NAME)
server = conn.compute.wait_for_server(server)
print("ssh -i {key} root@{ip}".format(
key=PRIVATE_KEYPAIR_FILE,
ip=server.access_ipv4))

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import examples.connect
"""
Find a resource from the Compute service.
@ -20,7 +22,7 @@ For a full guide see TODO(etoews):link to docs on developer.openstack.org
def find_image(conn):
print("Find Image:")
image = conn.compute.find_image("fedora-20.x86_64")
image = conn.compute.find_image(examples.connect.IMAGE_NAME)
print(image)
@ -30,8 +32,18 @@ def find_image(conn):
def find_flavor(conn):
print("Find Flavor:")
flavor = conn.compute.find_flavor("m1.small")
flavor = conn.compute.find_flavor(examples.connect.FLAVOR_NAME)
print(flavor)
return flavor
def find_keypair(conn):
print("Find Keypair:")
keypair = conn.compute.find_keypair(examples.connect.KEYPAIR_NAME)
print(keypair)
return keypair

View File

@ -36,3 +36,10 @@ def list_flavors(conn):
for flavor in conn.compute.flavors():
print(flavor)
def list_keypairs(conn):
print("List Keypairs:")
for keypair in conn.compute.keypairs():
print(keypair)

View File

@ -16,18 +16,53 @@ Connect to an OpenStack cloud.
For a full guide see TODO(etoews):link to docs on developer.openstack.org
"""
import os
import os_client_config
from openstack import connection
from openstack import profile
from openstack import utils
import sys
utils.enable_logging(True, stream=sys.stdout)
#: Defines the OpenStack Client Config (OCC) cloud key in your OCC config
#: file, typically in $HOME/.config/openstack/clouds.yaml. That configuration
#: will determine where the examples will be run and what resource defaults
#: will be used to run the examples.
TEST_CLOUD = os.getenv('OS_TEST_CLOUD', 'test_cloud')
class Opts(object):
def __init__(self, cloud='hp', debug=False):
self.cloud = cloud
def __init__(self, test_cloud='test_cloud', debug=False):
self.cloud = test_cloud
self.debug = debug
def _get_resource_value(resource_key, default):
try:
return cloud.config['example'][resource_key]
except KeyError:
return default
opts = Opts(test_cloud=TEST_CLOUD)
occ = os_client_config.OpenStackConfig()
cloud = occ.get_one_cloud(opts.cloud, argparse=opts)
IMAGE_NAME = _get_resource_value('image_name', 'fedora-20.x86_64')
FLAVOR_NAME = _get_resource_value('flavor_name', 'm1.small')
NETWORK_NAME = _get_resource_value('network_name', 'private')
KEYPAIR_NAME = _get_resource_value('keypair_name', 'openstacksdk-example')
PRIVATE_KEYPAIR_FILE = _get_resource_value('private_keypair_file',
"{home}/{ssh}/id_rsa.{key}".format(
home=os.getenv("HOME"),
ssh='.ssh',
key=KEYPAIR_NAME))
def create_connection_from_config():
return connection.from_config(Opts(cloud='test_cloud'))
return connection.from_config(opts)
def create_connection(auth_url, region, project_name, username, password):

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import examples.connect
"""
Find a resource from the Network service.
@ -20,7 +22,7 @@ For a full guide see TODO(etoews):link to docs on developer.openstack.org
def find_network(conn):
print("Find Network:")
network = conn.network.find_network("public")
network = conn.network.find_network(examples.connect.NETWORK_NAME)
print(network)

View File

@ -13,8 +13,8 @@
import unittest
from examples.compute import create
from examples.compute import find
from examples.compute import list
from examples.compute import find as compute_find
from examples.compute import list as compute_list
from examples import connect
from examples.network import find as network_find
from examples.network import list as network_list
@ -32,13 +32,15 @@ class TestCompute(unittest.TestCase):
cls.conn = connect.create_connection_from_config()
def test_compute(self):
list.list_servers(self.conn)
list.list_images(self.conn)
list.list_flavors(self.conn)
compute_list.list_servers(self.conn)
compute_list.list_images(self.conn)
compute_list.list_flavors(self.conn)
compute_list.list_keypairs(self.conn)
network_list.list_networks(self.conn)
image = find.find_image(self.conn)
flavor = find.find_flavor(self.conn)
network = network_find.find_network(self.conn)
compute_find.find_image(self.conn)
compute_find.find_flavor(self.conn)
compute_find.find_keypair(self.conn)
network_find.find_network(self.conn)
create.create_server(self.conn, 'example', image, flavor, network)
create.create_server(self.conn)