From 04f2f73c04a5e8db742060800a91748ec6ff6f03 Mon Sep 17 00:00:00 2001
From: darrenchan <dazzachan@yahoo.com.au>
Date: Tue, 10 Feb 2015 21:47:34 +1100
Subject: [PATCH] Migration of OpenStack SDK chapter

DocBook to RST conversion and clean up of:
1. OpenStack SDK chapter
2. Installing OpenStack SDK section
3. Authenticate section
4. Configure access and security for instances
5. Manage images section
6. Neutron section
7. Compute section
Change-Id: Idcc4bec15b0422fb0bddfde8f791b2b3e2a2cb43
---
 doc/playground-user-guide/source/index.rst    |   2 +-
 doc/playground-user-guide/source/sdk.rst      |  27 +
 .../source/sdk_authenticate.rst               |  17 +
 .../sdk_authenticate_compute_output.rst       | 538 +++++++++++++++
 .../sdk_authenticate_networking_endpoint.rst  | 612 ++++++++++++++++++
 ...dk_configure_access_security_instances.rst | 179 +++++
 .../source/sdk_install.rst                    |  11 +
 .../source/sdk_manage_images.rst              | 129 ++++
 8 files changed, 1514 insertions(+), 1 deletion(-)
 create mode 100644 doc/playground-user-guide/source/sdk.rst
 create mode 100644 doc/playground-user-guide/source/sdk_authenticate.rst
 create mode 100644 doc/playground-user-guide/source/sdk_authenticate_compute_output.rst
 create mode 100644 doc/playground-user-guide/source/sdk_authenticate_networking_endpoint.rst
 create mode 100644 doc/playground-user-guide/source/sdk_configure_access_security_instances.rst
 create mode 100644 doc/playground-user-guide/source/sdk_install.rst
 create mode 100644 doc/playground-user-guide/source/sdk_manage_images.rst

diff --git a/doc/playground-user-guide/source/index.rst b/doc/playground-user-guide/source/index.rst
index 47091dc7cb..d61d61bc5e 100644
--- a/doc/playground-user-guide/source/index.rst
+++ b/doc/playground-user-guide/source/index.rst
@@ -8,7 +8,7 @@ Contents:
 
    cli.rst
    dashboard.rst
-
+   sdk.rst
 
 Indices and tables
 ==================
diff --git a/doc/playground-user-guide/source/sdk.rst b/doc/playground-user-guide/source/sdk.rst
new file mode 100644
index 0000000000..fef0d9fbda
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk.rst
@@ -0,0 +1,27 @@
+====================
+OpenStack Python SDK
+====================
+
+The OpenStack Python Software Development Kit (SDK) is used to write Python
+automation scripts that create and manage resources in your OpenStack
+cloud. The SDK implements Python bindings to the OpenStack API, which
+enables you to perform automation tasks in Python by making calls on
+Python objects, rather than making REST calls directly. All OpenStack
+command-line tools are implemented using the Python SDK.
+
+You should also be familiar with:
+
+- RESTful web services
+- HTTP/1.1
+- JSON and XML data serialization formats
+
+.. toctree::
+   :maxdepth: 2
+
+   sdk_install.rst
+   sdk_authenticate.rst
+   sdk_manage_images.rst
+   sdk_configure_access_security_instances.rst
+   sdk_authenticate_networking_endpoint.rst
+   sdk_authenticate_compute_output.rst
+.. add sdk_assign_cors_headers.rst when migrated TODO(DC)
diff --git a/doc/playground-user-guide/source/sdk_authenticate.rst b/doc/playground-user-guide/source/sdk_authenticate.rst
new file mode 100644
index 0000000000..fa3ec1b50e
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk_authenticate.rst
@@ -0,0 +1,17 @@
+============
+Authenticate
+============
+
+When using the SDK, you must authenticate against an OpenStack endpoint
+before you can use OpenStack services. Each project uses a slightly
+different syntax for authentication.
+
+You must typically authenticate against a specific version of a service.
+For example, a client might need to authenticate against Identity v2.0.
+
+Python scripts that use the OpenStack SDK must have access to the
+credentials contained in the OpenStack RC file. Because credentials are
+sensitive information, do not include them in your scripts. This guide
+assumes that users source the PROJECT-openrc.sh file and access the
+credentials by using the environment variables in the Python scripts.
+
diff --git a/doc/playground-user-guide/source/sdk_authenticate_compute_output.rst b/doc/playground-user-guide/source/sdk_authenticate_compute_output.rst
new file mode 100644
index 0000000000..43f486864f
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk_authenticate_compute_output.rst
@@ -0,0 +1,538 @@
+=======
+Compute
+=======
+
+To use the information in this section, you must be familiar with
+OpenStack Compute.
+
+Set environment variables
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To set up environmental variables and authenticate against Compute API
+endpoints, see :role:`Authenticate <sdk_authenticate.rst>`.
+
+.. _get-openstack-credentials:
+
+Get OpenStack credentials (API v2)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This example uses the ``get_nova_credentials_v2`` method:
+
+.. code:: python
+
+    def get_nova_credentials_v2():
+        d = {}
+        d['version'] = '2'
+        d['username'] = os.environ['OS_USERNAME']
+        d['api_key'] = os.environ['OS_PASSWORD']
+        d['auth_url'] = os.environ['OS_AUTH_URL']
+        d['project_id'] = os.environ['OS_TENANT_NAME']
+        return d
+
+This code resides in the ``credentials.py`` file, which all samples
+import.
+
+Use the ``get_nova_credentials_v2()`` method to populate and get a
+dictionary:
+
+.. code:: python
+
+    credentials = get_nova_credentials_v2()
+
+List servers (API v2)
+~~~~~~~~~~~~~~~~~~~~~
+
+The following program lists servers by using the Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+
+2. Get Nova credentials. See :ref:`Get OpenStack credentials (API v2)
+<get-openstack-credentials>`.
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+4. List servers by calling ``servers.list`` on ``nova_client`` object:
+
+.. code:: python
+
+    print(nova_client.servers.list())
+
+List server code listing example
+--------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+
+    credentials = get_nova_credentials_v2()
+    nova_client = Client(**credentials)
+
+    print(nova_client.servers.list())
+
+Create server (API v2)
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following program creates a server (VM) by using the Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    import time
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+
+2. Get OpenStack credentials. See :ref:`Get OpenStack credentials (API v2)
+<get-openstack-credentials>`.
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+4. Get the flavor and image to use to create a server. This code uses
+the ``cirros`` image, the ``m1.tiny`` flavor, and the ``private``
+network:
+
+.. code:: python
+
+    image = nova_client.images.find(name="cirros")
+    flavor = nova_client.flavors.find(name="m1.tiny")
+    net = nova_client.networks.find(label="private")
+
+5. To create the server, use the network, image, and flavor:
+
+.. code:: python
+
+    nics = [{'net-id': net.id}]
+    instance = nova_client.servers.create(name="vm2", image=image,
+    flavor=flavor, key_name="keypair-1", nics=nics)
+
+6.  Run the "Sleep for five seconds" command, and determine whether
+the server/vm was
+created by calling ``nova_client.servers.list()``:
+
+.. code:: python
+
+    print("Sleeping for 5s after create command")
+    time.sleep(5)
+    print("List of VMs")
+    print(nova_client.servers.list())
+
+Create server code listing example
+----------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    import time
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+
+    try:
+        credentials = get_nova_credentials_v2()
+        nova_client = Client(**credentials)
+
+        image = nova_client.images.find(name="cirros")
+        flavor = nova_client.flavors.find(name="m1.tiny")
+        net = nova_client.networks.find(label="private")
+        nics = [{'net-id': net.id}]
+        instance = nova_client.servers.create(name="vm2", image=image,
+                                          flavor=flavor, key_name="keypair-1", nics=nics)
+        print("Sleeping for 5s after create command")
+        time.sleep(5)
+        print("List of VMs")
+        print(nova_client.servers.list())
+    finally:
+        print("Execution Completed")
+
+Delete server (API v2)
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following program deletes a server (VM) by using the Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    import time
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+
+2. Get Nova credentials. See :ref:`Get OpenStack credentials (API v2)
+<get-openstack-credentials>`.
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+4. Determine whether the ``vm1`` server exists:
+
+   a. List servers: ``servers_list``.
+
+   b. Iterate over ``servers_list`` and compare name with ``vm1``.
+
+   c. If true, set the variable name ``server_exists`` to ``True``
+   and break from the for loop:
+
+.. code:: python
+
+    servers_list = nova_client.servers.list()
+    server_del = "vm1"
+    server_exists = False
+
+    for s in servers_list:
+        if s.name == server_del:
+            print("This server %s exists" % server_del)
+            server_exists = True
+            break
+
+
+5. If the server exists, run the ``delete`` method of the
+``nova_client.servers`` object:
+
+.. code:: python
+
+    nova_client.servers.delete(s)
+
+Delete server code example
+--------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+
+    credentials = get_nova_credentials_v2()
+    nova_client = Client(**credentials)
+
+    servers_list = nova_client.servers.list()
+    server_del = "vm1"
+    server_exists = False
+
+    for s in servers_list:
+        if s.name == server_del:
+            print("This server %s exists" % server_del)
+            server_exists = True
+            break
+    if not server_exists:
+        print("server %s does not exist" % server_del)
+    else:
+        print("deleting server..........")
+        nova_client.servers.delete(s)
+        print("server %s deleted" % server_del)
+
+Update server (API v2)
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following program updates the name of a server (VM) by using the
+Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_server
+
+``print_server`` is a method defined in ``utils.py`` and prints the
+server details as shown in the code listing below:
+
+.. code:: python
+
+    def print_server(server):
+        print("-"*35)
+        print("server id: %s" % server.id)
+        print("server name: %s" % server.name)
+        print("server image: %s" % server.image)
+        print("server flavor: %s" % server.flavor)
+        print("server key name: %s" % server.key_name)
+        print("user_id: %s" % server.user_id)
+        print("-"*35)
+
+2. Get OpenStack Credentials. See :ref:`Get OpenStack credentials
+(API v2) <get-openstack-credentials>`.
+
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+
+4. Get the server instance using ``server_id`` and print the details by
+calling ``print_server`` method:
+
+.. code:: python
+
+    server_id = '99889c8d-113f-4a7e-970c-77f1916bfe14'
+    server = nova_client.servers.get(server_id)
+    n = server.name
+    print_server(server)
+
+
+5. Call ``server.update`` on the server object with the new value for
+``name`` variable:
+
+.. code:: python
+
+    server.update(name = n + '1')
+
+6. Get the updated instance of the server:
+
+.. code:: python
+
+    server_updated = nova_client.servers.get(server_id)
+
+7. Call ``print_server`` again to check the update server details:
+
+.. code:: python
+
+    print_server(server_updated)
+
+Update server code listing example
+----------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_server
+
+    credentials = get_nova_credentials_v2()
+    nova_client = Client(**credentials)
+
+    # Change the server_id specific to your environment
+
+    server_id = '99889c8d-113f-4a7e-970c-77f1916bfe14'
+    server = nova_client.servers.get(server_id)
+    n = server.name
+    print_server(server)
+
+    server.update(name=n +'1')
+    server_updated = nova_client.servers.get(server_id)
+    print_server(server_updated)
+
+List flavors (API v2)
+~~~~~~~~~~~~~~~~~~~~~
+
+The following program lists flavors and their details by using the
+Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_flavors
+
+The ``print_flavors`` method is defined in ``utils.py`` and prints the
+flavor details:
+
+.. code:: python
+
+    def print_flavors(flavor_list):
+        for flavor in flavor_list:
+           print("-"*35)
+           print("flavor id : %s" % flavor.id)
+           print("flavor name : %s" % flavor.name)
+        print("-"*35)
+
+2. Get OpenStack credentials. :ref:`Get OpenStack credentials
+(API v2) <get-openstack-credentials>`.
+
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+4. List flavors by calling ``list()`` on ``nova_client.flavors`` object:
+
+.. code:: python
+
+    flavors_list =  nova_client.flavors.list()
+
+5. Print the flavor details, id and name by calling ``print_flavors``:
+
+.. code:: python
+
+    print_flavors(flavors_list)
+
+List flavors code listing example
+---------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_flavors
+
+    credentials = get_nova_credentials_v2()
+    nova_client = Client(**credentials)
+
+    flavors_list = nova_client.flavors.list()
+    print_flavors(flavors_list)
+
+List floating IPs (API v2)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following program lists the floating IPs and their details by using
+the Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_values_ip
+
+The ``print_values_ip`` method is defined in ``utils.py`` and prints the
+floating\_ip object details:
+
+.. code:: python
+
+    def print_values_ip(ip_list):
+        ip_dict_lisl = []
+        for ip in ip_list:
+            print("-"*35)
+            print("fixed_ip : %s" % ip.fixed_ip)
+            print("id : %s" % ip.id)
+            print("instance_id : %s" % ip.instance_id)
+            print("ip : %s" % ip.ip)
+            print("pool : %s" % ip.pool)
+
+2. Get OpenStack credentials. See :ref:`Get OpenStack credentials
+(API v2) <get-openstack-credentials>`.
+
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+
+4. List floating IPs by calling ``list()`` on ``nova_client.floating_ips``
+object:
+
+.. code:: python
+
+    ip_list = nova_client.floating_ips.list()
+
+5. Print the floating IP object details by calling ``print_values_ip``:
+
+.. code:: python
+
+    print_values_ip(ip_list)
+
+List floating IPs code listing example
+--------------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_values_ip
+
+    credentials = get_nova_credentials_v2()
+    nova_client = Client(**credentials)
+    ip_list = nova_client.floating_ips.list()
+    print_values_ip(ip_list)
+
+List hosts (API v2)
+~~~~~~~~~~~~~~~~~~~
+
+The following program lists the hosts by using the Compute API v2.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_hosts
+
+The ``print_hosts`` method is defined in ``utils.py`` and prints the
+host object details:
+
+.. code:: python
+
+    def print_hosts(host_list):
+        for host in host_list:
+           print("-"*35)
+           print("host_name : %s" % host.host_name)
+           print("service : %s" % host.service)
+           print("zone : %s" % host.zone)
+        print("-"*35)
+
+2. Get OpenStack credentials. See :ref:`Get OpenStack credentials (API v2)
+<get-openstack-credentials>`.
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = Client(**credentials)
+
+4. List hosts by calling ``list()`` on ``nova_client.hosts`` object:
+
+.. code:: python
+
+    host_list = nova_client.hosts.list()
+
+5. Print the host object details by calling ``print_hosts(host_list)``:
+
+.. code:: python
+
+    print_hosts(host_list)
+
+List hosts code listing example
+-------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+
+    from credentials import get_nova_credentials_v2
+    from novaclient.client import Client
+    from utils import print_hosts
+
+    credentials = get_nova_credentials_v2()
+    nova_client = Client(**credentials)
+    host_list = nova_client.hosts.list()
+
+    print_hosts(host_list)
diff --git a/doc/playground-user-guide/source/sdk_authenticate_networking_endpoint.rst b/doc/playground-user-guide/source/sdk_authenticate_networking_endpoint.rst
new file mode 100644
index 0000000000..af9896733d
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk_authenticate_networking_endpoint.rst
@@ -0,0 +1,612 @@
+==========
+Networking
+==========
+
+To use the information in this section, you should have a general
+understanding of OpenStack Networking, OpenStack Compute, and the
+integration between the two. You should also have access to a plug-in
+that implements the Networking API v2.0.
+
+.. _set-environment-variables:
+
+Set environment variables
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Make sure that you set the relevant environment variables.
+
+As an example, see the sample shell file that sets these variables to
+get credentials:
+
+.. code:: bash
+
+    export OS_USERNAME="admin"
+    export OS_PASSWORD="password"
+    export OS_TENANT_NAME="admin"
+    export OS_AUTH_URL="http://IPADDRESS/v2.0"
+
+.. _get-credentials:
+
+Get credentials
+~~~~~~~~~~~~~~~
+
+The examples in this section use the ``get_credentials`` method:
+
+.. code:: python
+
+    def get_credentials():
+        d = {}
+        d['username'] = os.environ['OS_USERNAME']
+        d['password'] = os.environ['OS_PASSWORD']
+        d['auth_url'] = os.environ['OS_AUTH_URL']
+        d['tenant_name'] = os.environ['OS_TENANT_NAME']
+        return d
+
+This code resides in the ``credentials.py`` file, which all samples
+import.
+
+Use the ``get_credentials()`` method to populate and get a dictionary:
+
+.. code:: python
+
+    credentials = get_credentials()
+
+.. _get-nova-credentials:
+
+Get Nova credentials
+~~~~~~~~~~~~~~~~~~~~
+
+The examples in this section use the ``get_nova_credentials`` method:
+
+.. code:: python
+
+    def get_nova_credentials():
+        d = {}
+        d['username'] = os.environ['OS_USERNAME']
+        d['api_key'] = os.environ['OS_PASSWORD']
+        d['auth_url'] = os.environ['OS_AUTH_URL']
+        d['project_id'] = os.environ['OS_TENANT_NAME']
+        return d
+
+This code resides in the ``credentials.py`` file, which all samples
+import.
+
+Use the ``get_nova_credentials()`` method to populate and get a
+dictionary:
+
+.. code:: python
+
+    nova_credentials = get_nova_credentials()
+
+.. _print-values:
+
+Print values
+~~~~~~~~~~~~
+
+The examples in this section use the ``print_values`` and
+``print_values_server`` methods:
+
+.. code:: python
+
+    def print_values(val, type):
+        if type == 'ports':
+            val_list = val['ports']
+        if type == 'networks':
+            val_list = val['networks']
+        if type == 'routers':
+            val_list = val['routers']
+        for p in val_list:
+            for k, v in p.items():
+                print("%s : %s" % (k, v))
+            print('\n')
+
+
+    def print_values_server(val, server_id, type):
+        if type == 'ports':
+            val_list = val['ports']
+
+        if type == 'networks':
+            val_list = val['networks']
+        for p in val_list:
+            bool = False
+            for k, v in p.items():
+                if k == 'device_id' and v == server_id:
+                    bool = True
+            if bool:
+                for k, v in p.items():
+                    print("%s : %s" % (k, v))
+                print('\n')
+
+This code resides in the ``utils.py`` file, which all samples import.
+
+.. _create-network:
+
+Create network
+~~~~~~~~~~~~~~
+
+The following program creates a network:
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+
+    network_name = 'sample_network'
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    try:
+        body_sample = {'network': {'name': network_name,
+                       'admin_state_up': True}}
+
+        netw = neutron.create_network(body=body_sample)
+        net_dict = netw['network']
+        network_id = net_dict['id']
+        print('Network %s created' % network_id)
+
+        body_create_subnet = {'subnets': [{'cidr': '192.168.199.0/24',
+                              'ip_version': 4, 'network_id': network_id}]}
+
+        subnet = neutron.create_subnet(body=body_create_subnet)
+        print('Created subnet %s' % subnet)
+    finally:
+        print("Execution completed")
+
+.. _list-network:
+
+List networks
+~~~~~~~~~~~~~
+
+The following program lists networks:
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    netw = neutron.list_networks()
+
+    print_values(netw, 'networks')
+
+For ``print_values``, see :ref:`Print values <print-values>`.
+
+.. _create-ports:
+
+Create ports
+~~~~~~~~~~~~
+
+The following program creates a port:
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    import novaclient.v1_1.client as nvclient
+    from credentials import get_credentials
+    from credentials import get_nova_credentials
+
+    credentials = get_nova_credentials()
+    nova_client = nvclient.Client(**credentials)
+
+    # Replace with server_id and network_id from your environment
+
+    server_id = '9a52795a-a70d-49a8-a5d0-5b38d78bd12d'
+    network_id = 'ce5d204a-93f5-43ef-bd89-3ab99ad09a9a'
+    server_detail = nova_client.servers.get(server_id)
+    print(server_detail.id)
+
+    if server_detail != None:
+        credentials = get_credentials()
+        neutron = client.Client(**credentials)
+
+        body_value = {
+                         "port": {
+                                 "admin_state_up": True,
+                                 "device_id": server_id,
+                                 "name": "port1",
+                                 "network_id": network_id
+                          }
+                     }
+        response = neutron.create_port(body=body_value)
+        print(response)
+
+For ``get_nova_credentials``, see :ref:`Get Nova credentials
+<get-nova-credentials>`.
+
+For ``get_credentials``, see :ref:`Get credentials <get-credentials>`.
+
+.. _list-ports:
+
+List ports
+~~~~~~~~~~
+
+The following program lists ports:
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    ports = neutron.list_ports()
+    print_values(ports, 'ports')
+
+For ``get_credentials`` see :ref:`Get credentials <get-credentials>`.
+
+For ``print_values``, see :ref:`Print values <print-values>`.
+
+.. _list-server-ports:
+
+List server ports
+~~~~~~~~~~~~~~~~~
+
+The following program lists the ports for a server:
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    import novaclient.v1_1.client as nvclient
+    from credentials import get_credentials
+    from credentials import get_nova_credentials
+    from utils import print_values_server
+
+    credentials = get_nova_credentials()
+    nova_client = nvclient.Client(**credentials)
+
+    # change these values according to your environment
+
+    server_id = '9a52795a-a70d-49a8-a5d0-5b38d78bd12d'
+    network_id = 'ce5d204a-93f5-43ef-bd89-3ab99ad09a9a'
+    server_detail = nova_client.servers.get(server_id)
+    print(server_detail.id)
+
+    if server_detail is not None:
+        credentials = get_credentials()
+        neutron = client.Client(**credentials)
+        ports = neutron.list_ports()
+
+        print_values_server(ports, server_id, 'ports')
+        body_value = {'port': {
+            'admin_state_up': True,
+            'device_id': server_id,
+            'name': 'port1',
+            'network_id': network_id,
+            }}
+
+        response = neutron.create_port(body=body_value)
+        print(response)
+
+.. _create-port-add-port-subnet:
+
+Create router and add port to subnet
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This example queries OpenStack Networking to create a router and add a
+port to a subnet.
+
+
+1. Import the following modules:
+
+.. code:: python
+
+    from neutronclient.v2_0 import client
+    import novaclient.v1_1.client as nvclient
+    from credentials import get_credentials
+    from credentials import get_nova_credentials
+    from utils import print_values_server
+
+2. Get Nova Credentials. See :ref:'Get Nova credentials
+<get-nova-credentials>'.
+
+3. Instantiate the ``nova_client`` client object by using the
+``credentials`` dictionary object:
+
+.. code:: python
+
+    nova_client = nvclient.Client(**credentials)
+
+4. Create a router and add a port to the subnet:
+
+.. code:: python
+
+    # Replace with network_id from your environment
+
+    network_id = '81bf592a-9e3f-4f84-a839-ae87df188dc1'
+
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    neutron.format = json
+    request = {'router': {'name': 'router name',
+                          'admin_state_up': True}}
+
+    router = neutron.create_router(request)
+    router_id = router['router']['id']
+    # for example: '72cf1682-60a8-4890-b0ed-6bad7d9f5466'
+    router = neutron.show_router(router_id)
+    print(router)
+    body_value = {'port': {
+        'admin_state_up': True,
+        'device_id': router_id,
+        'name': 'port1',
+        'network_id': network_id,
+        }}
+
+    response = neutron.create_port(body=body_value)
+    print(response)
+    print("Execution Completed")
+
+Create router: complete code listing example
+--------------------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    import novaclient.v1_1.client as nvclient
+    from credentials import get_credentials
+    from credentials import get_nova_credentials
+    from utils import print_values_server
+
+    credentials = get_nova_credentials()
+    nova_client = nvclient.Client(**credentials)
+
+    # Replace with network_id from your environment
+
+    network_id = '81bf592a-9e3f-4f84-a839-ae87df188dc1'
+    try:
+        credentials = get_credentials()
+        neutron = client.Client(**credentials)
+        neutron.format = 'json'
+        request = {'router': {'name': 'router name',
+                              'admin_state_up': True}}
+        router = neutron.create_router(request)
+        router_id = router['router']['id']
+        # for example: '72cf1682-60a8-4890-b0ed-6bad7d9f5466'
+        router = neutron.show_router(router_id)
+        print(router)
+        body_value = {'port': {
+            'admin_state_up': True,
+            'device_id': router_id,
+            'name': 'port1',
+            'network_id': network_id,
+            }}
+
+        response = neutron.create_port(body=body_value)
+        print(response)
+    finally:
+        print("Execution completed")
+
+.. _delete-network:
+
+Delete a network
+~~~~~~~~~~~~~~~~
+
+This example queries OpenStack Networking to delete a network.
+
+To delete a network
+
+1. Import the following modules:
+
+.. code:: python
+
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+
+2. Get credentials. See :ref:`Get Nova credentials <get-nova-credentials>`.
+
+3. Instantiate the ``neutron`` client object by using the ``credentials``
+dictionary object:
+
+.. code:: python
+
+    neutron = client.Client(**credentials)
+
+4. Delete the network:
+
+.. code:: python
+
+    body_sample = {'network': {'name': network_name,
+                   'admin_state_up': True}}
+
+    netw = neutron.create_network(body=body_sample)
+    net_dict = netw['network']
+    network_id = net_dict['id']
+    print('Network %s created' % network_id)
+
+    body_create_subnet = {'subnets': [{'cidr': '192.168.199.0/24',
+                          'ip_version': 4, 'network_id': network_id}]}
+
+    subnet = neutron.create_subnet(body=body_create_subnet)
+    print('Created subnet %s' % subnet)
+
+    neutron.delete_network(network_id)
+    print('Deleted Network %s' % network_id)
+
+    print("Execution completed")
+
+Delete network: complete code listing example
+---------------------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+
+    network_name = 'temp_network'
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    try:
+        body_sample = {'network': {'name': network_name,
+                       'admin_state_up': True}}
+
+        netw = neutron.create_network(body=body_sample)
+        net_dict = netw['network']
+        network_id = net_dict['id']
+        print('Network %s created' % network_id)
+
+        body_create_subnet = {'subnets': [{'cidr': '192.168.199.0/24',
+                              'ip_version': 4, 'network_id': network_id}]}
+
+        subnet = neutron.create_subnet(body=body_create_subnet)
+        print('Created subnet %s' % subnet)
+
+        neutron.delete_network(network_id)
+        print('Deleted Network %s' % network_id)
+    finally:
+        print("Execution Completed")
+
+.. _list-routers:
+
+List routers
+~~~~~~~~~~~~
+
+This example queries OpenStack Networking to list all routers.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+2. Get credentials. See :ref:`Get Nova credentials <get-nova-credentials>`.
+
+3. Instantiate the ``neutron`` client object by using the ``credentials``
+dictionary object:
+
+.. code:: python
+
+    neutron = client.Client(**credentials)
+
+4. List the routers:
+
+.. code:: python
+
+    routers_list = neutron.list_routers(retrieve_all=True)
+    print_values(routers_list, 'routers')
+    print("Execution completed")
+
+For ``print_values``, see :ref:`Print values <print-values>`.
+
+List routers: complete code listing example
+-------------------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+    try:
+        credentials = get_credentials()
+        neutron = client.Client(**credentials)
+        routers_list = neutron.list_routers(retrieve_all=True)
+        print_values(routers_list, 'routers')
+    finally:
+        print("Execution completed")
+
+.. _list-security-groups:
+
+List security groups
+~~~~~~~~~~~~~~~~~~~~
+
+This example queries OpenStack Networking to list security groups.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+2. Get credentials. See :ref:`Get credentials <get-credentials>`.
+
+3. Instantiate the ``neutron`` client object by using the ``credentials``
+dictionary object:
+
+.. code:: python
+
+    neutron = client.Client(**credentials)
+
+4. List Security groups
+
+.. code:: python
+
+    sg = neutron.list_security_groups()
+    print(sg)
+
+List security groups: complete code listing example
+---------------------------------------------------
+
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    sg = neutron.list_security_groups()
+    print(sg)
+
+    **Note**
+
+    OpenStack Networking security groups are case-sensitive while the
+    nova-network security groups are case-insensitive.
+
+.. _list-subnets:
+
+List subnets
+~~~~~~~~~~~~
+
+This example queries OpenStack Networking to list subnets.
+
+1. Import the following modules:
+
+.. code:: python
+
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+2. Get credentials. See :ref:'Get credentials <get-credentials>'.
+
+3. Instantiate the ``neutron`` client object by using the ``credentials``
+dictionary object:
+
+.. code:: python
+
+    neutron = client.Client(**credentials)
+
+4. List subnets:
+
+.. code:: python
+
+    subnets = neutron.list_subnets()
+    print(subnets)
+
+List subnets: complete code listing example
+-------------------------------------------
+.. code:: python
+
+    #!/usr/bin/env python
+    from neutronclient.v2_0 import client
+    from credentials import get_credentials
+    from utils import print_values
+
+    credentials = get_credentials()
+    neutron = client.Client(**credentials)
+    subnets = neutron.list_subnets()
+    print(subnets)
diff --git a/doc/playground-user-guide/source/sdk_configure_access_security_instances.rst b/doc/playground-user-guide/source/sdk_configure_access_security_instances.rst
new file mode 100644
index 0000000000..1fff10ce27
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk_configure_access_security_instances.rst
@@ -0,0 +1,179 @@
+===========================================
+Configure access and security for instances
+===========================================
+
+When working with images in the SDK, you will call ``novaclient``
+methods.
+
+.. _add-keypair:
+
+Add a keypair
+~~~~~~~~~~~~~
+
+To generate a keypair, call the
+`novaclient.v1\_1.keypairs.KeypairManager.create <http://docs.
+openstack.org/developer/python-novaclient/api/novaclient.v1_1.keypairs
+.html#novaclient.v1_1.keypairs.KeypairManager.create>`__ method:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    keypair_name = "staging"
+    keypair = nova.keypairs.create(name=keypair_name)
+    print keypair.private_key
+
+The Python script output looks something like this:
+
+::
+
+    -----BEGIN RSA PRIVATE KEY-----
+    MIIEowIBAAKCAQEA8XkaMqInSPfy0hMfWO+OZRtIgrQAbQkNcaNHmv2GN2G6xZlb\nuBRux5Xk/6SZ
+    ABaNPm1nRWm/ZDHnxCsFTcAl2LYOQXx3Cl2qKNY4r2di4G48GAkd\n7k5lDP2RgQatUM8npO0CD9PU
+    ...
+    mmrceYYK08/lQ7JKLmVkdzdQKt77+v1oBBuHiykLfI6h1m77NRDw9r8cV\nzczYeoALifpjTPMkKS8
+    ECfDCuDn/vc9K1He8CRaJHf8AMLQLM3MN
+    -----END RSA PRIVATE KEY-----
+
+You typically write the private key to a file to use it later. The
+file must be readable and writeable by only the file owner; otherwise,
+the SSH client will refuse to read the private key file. The safest way
+is to create the file with the appropriate permissions, as shown in the
+following example:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    import os
+    nova = nvclient.Client(...)
+    keypair_name = "staging"
+    private_key_filename = "/home/alice/id-staging"
+    keypair = nova.keypairs.create(name=keypair_name)
+
+    # Create a file for writing that can only be read and written by
+    owner
+    fp = os.open(private_key_filename, os.O_WRONLY | os.O_CREAT, 0o600)
+    with os.fdopen(fp, 'w') as f:
+        f.write(keypair.private_key)
+
+.. _import-keypair:
+
+Import a keypair
+~~~~~~~~~~~~~~~~
+
+If you have already generated a keypair with the public key located at
+``~/.ssh/id_rsa.pub``, pass the contents of the file to the
+`novaclient.v1\_1.keypairs.KeypairManager.create <http://docs.
+openstack.org/developer/python-novaclient/api/novaclient.v1_1.keypairs
+.html#novaclient.v1_1.keypairs.KeypairManager.create>`__ method to
+import the public key to Compute:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    import os.path
+    with open(os.path.expanduser('~/.ssh/id_rsa.pub')) as f:
+        public_key = f.read()
+    nova = nvclient.Client(...)
+    nova.keypairs.create('mykey', public_key)
+
+.. _list-keypair:
+
+List keypairs
+~~~~~~~~~~~~~
+
+To list keypairs, call the
+`novaclient.v1\_1.keypairs.KeypairManager.list <http://docs.openstack.
+org/developer/python-novaclient/api/novaclient.v1_1.keypairs.html
+#novaclient.v1_1.keypairs.KeypairManager.list>`__ method:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    keypairs = nova.keypairs.list()
+
+.. _create-manage-security-groups:
+
+Create and manage security groups
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To list security groups for the current project, call the
+`novaclient.v\_1.security\_groups.SecurityGroupManager.list
+<http://docs.openstack.org/developer/python-novaclient/api/novaclient
+.v1_1.security_groups.html#novaclient.v1_1.security_groups.
+SecurityGroupManager.list>`__ method:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    security_groups = nova.security_groups.list()
+
+To create a security group with a specified name and description, call
+the `novaclient.v\_1.security\_groups.SecurityGroupManager.create
+<http://docs.openstack.org/developer/python-novaclient/api/novaclient.
+v1_1.security_groups.html#novaclient.v1_1.security_groups.
+SecurityGroupManager.create>`__ method:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    nova.security_groups.create(name="web", description="Web servers")
+
+To delete a security group, call the
+`novaclient.v\_1.security\_groups.SecurityGroupManager.delete
+<http://docs.openstack.org/developer/python-novaclient/api/novaclient.
+v1_1.security_groups.html#novaclient.v1_1.security_groups.
+SecurityGroupManager.delete>`__ method, passing either a
+`novaclient.v1\_1.security\_groups.SecurityGroup
+<http://docs.openstack.org/developer/python-novaclient/api/novaclient
+.v1_1.security_groups.html#novaclient.v1_1.security_groups.
+SecurityGroup>`__ object or group ID as an argument:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    group = nova.security_groups.find(name="web")
+    nova.security_groups.delete(group)
+    # The following lines would also delete the group:
+    # nova.security_groups.delete(group.id)
+    # group.delete()
+
+.. _create-manage-security-group-rules:
+
+Create and manage security group rules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Access the security group rules from the ``rules`` attribute of a
+`novaclient.v1\_1.security\_groups.SecurityGroup <http://docs.
+openstack.org/developer/python-novaclient/api/novaclient.v1_1.security
+_groups.html#novaclient.v1_1.security_groups.SecurityGroup>`__ object:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    group = nova.security_groups.find(name="web")
+    print group.rules
+
+To add a rule to a security group, call the
+`novaclient.v1\_1.security\_group\_rules.SecurityGroupRuleManager.
+create <http://docs.openstack.org/developer/python-novaclient/api/
+novaclient.v1_1.security_group_rules.html#novaclient.v1_1.
+security_group_rules.SecurityGroupRuleManager.create>`__ method:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    nova = nvclient.Client(...)
+    group = nova.security_groups.find(name="web")
+    # Add rules for ICMP, tcp/80 and tcp/443
+    nova.security_group_rules.create(group.id, ip_protocol="icmp",
+                                     from_port=-1, to_port=-1)
+    nova.security_group_rules.create(group.id, ip_protocol="tcp",
+                                     from_port=80, to_port=80)
+    nova.security_group_rules.create(group.id, ip_protocol="tcp",
+                                     from_port=443, to_port=443)
diff --git a/doc/playground-user-guide/source/sdk_install.rst b/doc/playground-user-guide/source/sdk_install.rst
new file mode 100644
index 0000000000..a75a902234
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk_install.rst
@@ -0,0 +1,11 @@
+Installing OpenStack SDK
+-------------------------
+
+Each OpenStack project has its own Python library. These libraries are
+bundled with the command-line clients. For example, the Python bindings
+for the Compute API are bundled with the python-novaclient package.
+
+For details about how to install the clients, see
+
+.. add Install the OpenStack command-line clients link when migrated TODO(DC)
+
diff --git a/doc/playground-user-guide/source/sdk_manage_images.rst b/doc/playground-user-guide/source/sdk_manage_images.rst
new file mode 100644
index 0000000000..22588bfc86
--- /dev/null
+++ b/doc/playground-user-guide/source/sdk_manage_images.rst
@@ -0,0 +1,129 @@
+=============
+Manage images
+=============
+
+When working with images in the SDK, you will call both ``glance`` and
+``nova`` methods.
+
+.. _list-images:
+
+List images
+~~~~~~~~~~~
+
+To list the available images, call the
+``glanceclient.v2.images.Controller.list`` method:
+
+.. code:: python
+
+    import glanceclient.v2.client as glclient
+    glance = glclient.Client(...)
+    images = glance.images.list()
+
+The images method returns a Python generator, as shown in the following
+interaction with the Python interpreter:
+
+::
+
+    >>> images = glance.images.list()
+    >>> images
+    <generator object list at 0x105e9c2d0>
+    >>> list(images)
+    [{u'checksum': u'f8a2eeee2dc65b3d9b6e63678955bd83',
+      u'container_format': u'ami',
+      u'created_at': u'2013-10-20T14:28:10Z',
+      u'disk_format': u'ami',
+      u'file': u'/v2/images/dbc9b2db-51d7-403d-b680-3f576380b00c/file',
+      u'id': u'dbc9b2db-51d7-403d-b680-3f576380b00c',
+      u'kernel_id': u'c002c82e-2cfa-4952-8461-2095b69c18a6',
+      u'min_disk': 0,
+      u'min_ram': 0,
+      u'name': u'cirros-0.3.2-x86_64-uec',
+      u'protected': False,
+      u'ramdisk_id': u'4c1c9b4f-3fe9-425a-a1ec-1d8fd90b4db3',
+      u'schema': u'/v2/schemas/image',
+      u'size': 25165824,
+      u'status': u'active',
+      u'tags': [],
+      u'updated_at': u'2013-10-20T14:28:11Z',
+      u'visibility': u'public'},
+     {u'checksum': u'69c33642f44ca552ba4bb8b66ad97e85',
+      u'container_format': u'ari',
+      u'created_at': u'2013-10-20T14:28:09Z',
+      u'disk_format': u'ari',
+      u'file': u'/v2/images/4c1c9b4f-3fe9-425a-a1ec-1d8fd90b4db3/file',
+      u'id': u'4c1c9b4f-3fe9-425a-a1ec-1d8fd90b4db3',
+      u'min_disk': 0,
+      u'min_ram': 0,
+      u'name': u'cirros-0.3.2-x86_64-uec-ramdisk',
+      u'protected': False,
+      u'schema': u'/v2/schemas/image',
+      u'size': 3714968,
+      u'status': u'active',
+      u'tags': [],
+      u'updated_at': u'2013-10-20T14:28:10Z',
+      u'visibility': u'public'},
+     {u'checksum': u'c352f4e7121c6eae958bc1570324f17e',
+      u'container_format': u'aki',
+      u'created_at': u'2013-10-20T14:28:08Z',
+      u'disk_format': u'aki',
+      u'file': u'/v2/images/c002c82e-2cfa-4952-8461-2095b69c18a6/file',
+      u'id': u'c002c82e-2cfa-4952-8461-2095b69c18a6',
+      u'min_disk': 0,
+      u'min_ram': 0,
+      u'name': u'cirros-0.3.2-x86_64-uec-kernel',
+      u'protected': False,
+      u'schema': u'/v2/schemas/image',
+      u'size': 4955792,
+      u'status': u'active',
+      u'tags': [],
+      u'updated_at': u'2013-10-20T14:28:09Z',
+      u'visibility': u'public'}]
+
+.. _get-image-id:
+
+Get image by ID
+~~~~~~~~~~~~~~~
+
+To retrieve an image object from its ID, call the
+``glanceclient.v2.images.Controller.get`` method:
+
+.. code:: python
+
+    import glanceclient.v2.client as glclient
+    image_id = 'c002c82e-2cfa-4952-8461-2095b69c18a6'
+    glance = glclient.Client(...)
+    image = glance.images.get(image_id)
+
+.. _get-image-name:
+
+Get image by name
+~~~~~~~~~~~~~~~~~
+
+The Image Service Python bindings do not support the retrieval of an
+image object by name. However, the Compute Python bindings enable you to
+get an image object by name. To get an image object by name, call the
+``novaclient.v1\_1.images.ImageManager.find`` method:
+
+.. code:: python
+
+    import novaclient.v1_1.client as nvclient
+    name = "cirros"
+    nova = nvclient.Client(...)
+    image = nova.images.find(name=name)
+
+.. _upload-image:
+
+Upload an image
+~~~~~~~~~~~~~~~
+
+To upload an image, call the ``glanceclient.v2.images.ImageManager.create``
+method:
+
+.. code:: python
+
+    import glanceclient.v2.client as glclient
+    imagefile = "/tmp/myimage.img"
+    glance = glclient.Client(...)
+    with open(imagefile) as fimage:
+      glance.images.create(name="myimage", is_public=False, disk_format="qcow2",
+                           container_format="bare", data=fimage)