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:
parent
49922f340c
commit
7b33afc2e9
0
examples/__init__.py
Normal file
0
examples/__init__.py
Normal file
237
examples/common.py
Executable file
237
examples/common.py
Executable 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
64
examples/transport.py
Executable 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))
|
Loading…
Reference in New Issue
Block a user