Add some sample scripts

This is a very basic starting point for working code example usage of
the SDK.

The common module includes an argument parser that recognizes the common
authentication arguments so setting up auth against a running OpenStack
cloud is the same as the library CLIs.

The inital example for Transport is a couple of simple GETs that also
shows the connection pooling.

Change-Id: I07de2888471a39cbc43daedded36ad683d02a472
This commit is contained in:
Dean Troyer 2014-04-16 01:08:00 -05:00 committed by Terry Howe
parent 49922f340c
commit 7b33afc2e9
3 changed files with 301 additions and 0 deletions

0
examples/__init__.py Normal file
View File

237
examples/common.py Executable file
View File

@ -0,0 +1,237 @@
#!/usr/bin/env python
# common.py - Common bits for SDK examples
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
SDK Examples
This is a collection of common functions used by the example scripts.
It may also be run as a script to do the most basic check of creating
a Transport object.
common.object_parser() provides the common set of command-line arguments
used in the library CLIs for setting up authentication. This should make
playing with the example scripts against a running OpenStack simpler.
"""
import argparse
import logging
import os
import subprocess
import sys
import traceback
from openstack import transport
CONSOLE_MESSAGE_FORMAT = '%(levelname)s: %(name)s %(message)s'
DEFAULT_VERBOSE_LEVEL = 1
USER_AGENT = 'qwiktest'
_logger = logging.getLogger(__name__)
def get_open_fds():
'''Return the open file descriptors for current process
.. warning: will only work on UNIX-like os-es.
'''
pid = os.getpid()
procs = subprocess.check_output(
["lsof", '-w', '-Fftn0', "-p", str(pid)]
)
print('procs: %s' % procs)
print('netstat: %s' % subprocess.check_output(['netstat', '-nlt']))
procs_list = filter(
lambda s: s and s[0] == 'f' and s[1].isdigit(),
procs.split('\n')
)
return [d.replace('\000', '|') for d in procs_list]
def make_transport(opts):
"""Create a transport given some options."""
# Certificate verification - defaults to True
if opts.os_cacert:
verify = opts.os_cacert
else:
verify = not opts.insecure
trans = transport.Transport(
verify=verify,
user_agent=USER_AGENT,
)
return trans
def run(opts):
print("start fds: %s" % get_open_fds())
# Set up common client transport
trans = make_transport(opts)
# Do something interesting here?
print("transport: %s" % trans)
print("end fds: %s" % get_open_fds())
def env(*vars, **kwargs):
"""Search for the first defined of possibly many env vars
Returns the first environment variable defined in vars, or
returns the default defined in kwargs.
"""
for v in vars:
value = os.environ.get(v, None)
if value:
return value
return kwargs.get('default', '')
def option_parser():
"""Set up some of the common CLI options
These are the basic options that match the library CLIs so
command-line/environment setups for those also work with these
demonstration programs.
"""
parser = argparse.ArgumentParser(
description='A demonstration framework')
# Global arguments
parser.add_argument(
'--os-auth-url',
metavar='<auth-url>',
default=env('OS_AUTH_URL'),
help='Authentication URL (Env: OS_AUTH_URL)',
)
parser.add_argument(
'--os-project-name',
metavar='<auth-project-name>',
default=env('OS_PROJECT_NAME', default=env('OS_TENANT_NAME')),
help='Project name of the requested project-level'
'authorization scope (Env: OS_PROJECT_NAME)',
)
parser.add_argument(
'--os-username',
metavar='<auth-username>',
default=env('OS_USERNAME'),
help='Authentication username (Env: OS_USERNAME)',
)
parser.add_argument(
'--os-password',
metavar='<auth-password>',
default=env('OS_PASSWORD'),
help='Authentication password (Env: OS_PASSWORD)',
)
parser.add_argument(
'--os-cacert',
metavar='<ca-bundle-file>',
default=env('OS_CACERT'),
help='CA certificate bundle file (Env: OS_CACERT)',
)
verify_group = parser.add_mutually_exclusive_group()
verify_group.add_argument(
'--verify',
action='store_true',
help='Verify server certificate (default)',
)
verify_group.add_argument(
'--insecure',
action='store_true',
help='Disable server certificate verification',
)
parser.add_argument(
'--os-identity-api-version',
metavar='<identity-api-version>',
default=env(
'OS_IDENTITY_API_VERSION',
default=None),
help='Force Identity API version (Env: OS_IDENTITY_API_VERSION)',
)
parser.add_argument(
'--os-token',
metavar='<token>',
default=env('OS_TOKEN'),
help='Defaults to env[OS_TOKEN]',
)
parser.add_argument(
'--os-url',
metavar='<url>',
default=env('OS_URL'),
help='Defaults to env[OS_URL]',
)
parser.add_argument(
'-v', '--verbose',
action='count',
dest='verbose_level',
default=1,
help='Increase verbosity of output. Can be repeated.',
)
parser.add_argument(
'--debug',
default=False,
action='store_true',
help='show tracebacks on errors',
)
return parser
def configure_logging(opts):
"""Typical app logging setup
Based on OSC/cliff
"""
root_logger = logging.getLogger('')
# Always send higher-level messages to the console via stderr
console = logging.StreamHandler(sys.stderr)
formatter = logging.Formatter(CONSOLE_MESSAGE_FORMAT)
console.setFormatter(formatter)
root_logger.addHandler(console)
if opts.debug:
root_logger.setLevel(logging.DEBUG)
else:
root_logger.setLevel(logging.WARNING)
return
def setup():
opts = option_parser().parse_args()
configure_logging(opts)
return opts
def main(opts, run):
try:
return run(opts)
except Exception as e:
if opts.debug:
_logger.error(traceback.format_exc(e))
else:
_logger.error('Exception raised: ' + str(e))
return 1
if __name__ == "__main__":
opts = setup()
sys.exit(main(opts, run))

64
examples/transport.py Executable file
View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
# transport.py - Example transport usage
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
SDK Transport Examples
This script shows the basic use of the Transport class in making
REST API calls.
"""
import sys
from examples import common
def do_transport(opts):
trans = common.make_transport(opts)
# Get the version data from the auth URL
resp = trans.get(opts.os_auth_url).json()
ver = resp['version']
print("\nAuth URL: %s" % opts.os_auth_url)
print(" version: %s" % ver['id'])
print(" status: %s" % ver['status'])
# Do a basic call to somewhere fun
url = 'https://api.github.com/users/openstack'
resp = trans.get(url).json()
print("\nGitHub API URL: %s" % url)
print(" gists: %s" % resp['gists_url'])
print(" repos: %s" % resp['public_repos'])
url = 'https://api.github.com/users/openstack-dev'
resp = trans.get(url).json()
print("\nGitHub API URL: %s" % url)
print(" gists: %s" % resp['gists_url'])
print(" repos: %s" % resp['public_repos'])
# stats
print('\nTransport connection pools:')
print(" http pool: %s" % (
trans.adapters['http://'].poolmanager.pools.keys(),
))
print(" https pool: %s" % (
trans.adapters['https://'].poolmanager.pools.keys(),
))
if __name__ == "__main__":
opts = common.setup()
sys.exit(common.main(opts, do_transport))