]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Move heat-cfn, heat-boto, heat-watch to new repo
authorSteve Baker <sbaker@redhat.com>
Mon, 22 Jul 2013 04:01:44 +0000 (16:01 +1200)
committerSteve Baker <sbaker@redhat.com>
Tue, 13 Aug 2013 00:26:43 +0000 (12:26 +1200)
The new home for these tools is
https://github.com/openstack-dev/heat-cfnclient

These tools are now aimed at heat developers only
and they will not be released or packaged.

Change-Id: I1ea62ef17e81ab53cacb5e4940f0c4e2516ed383

22 files changed:
bin/heat-boto [deleted symlink]
bin/heat-cfn [deleted file]
bin/heat-watch [deleted file]
doc/source/conf.py
doc/source/man/heat-boto.rst [deleted file]
doc/source/man/heat-cfn.rst [deleted file]
doc/source/man/heat-watch.rst [deleted file]
doc/source/man/index.rst
etc/bash_completion.d/heat-cfn [deleted file]
etc/boto.cfg [deleted file]
heat/cfn_client/__init__.py [deleted file]
heat/cfn_client/boto_client.py [deleted file]
heat/cfn_client/boto_client_cloudwatch.py [deleted file]
heat/cfn_client/client.py [deleted file]
heat/cfn_client/utils.py [deleted file]
heat/common/auth.py [deleted file]
heat/common/client.py [deleted file]
heat/common/utils.py [deleted file]
heat/tests/test_cli.py [deleted file]
requirements.txt
setup.cfg
tools/uninstall-heat

diff --git a/bin/heat-boto b/bin/heat-boto
deleted file mode 120000 (symlink)
index 4b4c848..0000000
+++ /dev/null
@@ -1 +0,0 @@
-heat-cfn
\ No newline at end of file
diff --git a/bin/heat-cfn b/bin/heat-cfn
deleted file mode 100755 (executable)
index 34a5bd0..0000000
+++ /dev/null
@@ -1,693 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-#    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.
-
-"""
-This is the administration program for heat. It is simply a command-line
-interface for adding, modifying, and retrieving information about the stacks
-belonging to a user.  It is a convenience application that talks to the heat
-API server.
-"""
-
-import optparse
-import os
-import os.path
-import sys
-import time
-import logging
-
-import httplib
-from urlparse import urlparse
-# If ../heat/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'heat', '__init__.py')):
-    sys.path.insert(0, possible_topdir)
-
-scriptname = os.path.basename(sys.argv[0])
-
-from heat.openstack.common import gettextutils
-
-gettextutils.install('heat', lazy=True)
-
-if scriptname == 'heat-boto':
-    from heat.cfn_client import boto_client as heat_client
-else:
-    from heat.cfn_client import client as heat_client
-from heat.version import version_info as version
-from heat.common import config
-from heat.common import exception
-from heat.cfn_client import utils
-from keystoneclient.v2_0 import client
-
-
-def get_swift_template(options):
-    '''
-    Retrieve a template from the swift object store, using
-    the provided URL.  We request a keystone token to authenticate
-    '''
-    template_body = None
-    if options.auth_strategy == 'keystone':
-        # we use the keystone credentials to get a token
-        # to pass in the request header
-        keystone = client.Client(username=options.username,
-                                 password=options.password,
-                                 tenant_name=options.tenant,
-                                 auth_url=options.auth_url)
-        logging.info("Getting template from swift URL: %s" %
-                     options.template_object)
-        url = urlparse(options.template_object)
-        if url.scheme == 'https':
-            conn = httplib.HTTPSConnection(url.netloc)
-        else:
-            conn = httplib.HTTPConnection(url.netloc)
-        headers = {'X-Auth-Token': keystone.auth_token}
-        conn.request("GET", url.path, headers=headers)
-        r1 = conn.getresponse()
-        logging.info('status %d' % r1.status)
-        if r1.status == 200:
-            template_body = r1.read()
-            conn.close()
-    else:
-        logging.error("template-object option requires keystone")
-
-    return template_body
-
-
-def get_template_param(options):
-    '''
-    Helper function to extract the template in whatever
-    format has been specified by the cli options
-    '''
-    param = {}
-    if options.template_file:
-        param['TemplateBody'] = open(options.template_file).read()
-    elif options.template_url:
-        param['TemplateUrl'] = options.template_url
-    elif options.template_object:
-        template_body = get_swift_template(options)
-        if template_body:
-            param['TemplateBody'] = template_body
-        else:
-            logging.error("Error reading swift template")
-
-    return param
-
-
-@utils.catch_error('validate')
-def template_validate(options, arguments):
-    '''
-    Validate a template.  This command parses a template and verifies that
-    it is in the correct format.
-
-    Usage: heat-cfn validate \\
-        [--template-file=<template file>|--template-url=<template URL>] \\
-        [options]
-
-    --template-file: Specify a local template file.
-    --template-url:  Specify a URL pointing to a stack description template.
-    '''
-    parameters = {}
-    templ_param = get_template_param(options)
-    if templ_param:
-        parameters.update(templ_param)
-    else:
-        logging.error('Please specify a template file or url')
-        return utils.FAILURE
-
-    c = get_client(options)
-    parameters.update(c.format_parameters(options))
-    result = c.validate_template(**parameters)
-    print c.format_template(result)
-
-
-@utils.catch_error('estimatetemplatecost')
-def estimate_template_cost(options, arguments):
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Please specify the stack name you wish to estimate")
-        logging.error("as the first argument")
-        return utils.FAILURE
-
-    templ_param = get_template_param(options)
-    if templ_param:
-        parameters.update(templ_param)
-    else:
-        logging.error('Please specify a template file or url')
-        return utils.FAILURE
-
-    c = get_client(options)
-    parameters.update(c.format_parameters(options))
-    result = c.estimate_template_cost(**parameters)
-    print result
-
-
-@utils.catch_error('gettemplate')
-def get_template(options, arguments):
-    '''
-    Gets an existing stack template.
-    '''
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Please specify the stack you wish to get")
-        logging.error("as the first argument")
-        return utils.FAILURE
-
-    c = get_client(options)
-    result = c.get_template(**parameters)
-    print result
-
-
-@utils.catch_error('create')
-def stack_create(options, arguments):
-    '''
-    Create a new stack from a template.
-
-    Usage: heat-cfn create <stack name> \\
-        [--template-file=<template file>|--template-url=<template URL>] \\
-        [options]
-
-    Stack Name: The user specified name of the stack you wish to create.
-
-    --template-file: Specify a local template file containing a valid
-                     stack description template.
-    --template-url:  Specify a URL pointing to a valid stack description
-                     template.
-    '''
-
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Please specify the stack name you wish to create")
-        logging.error("as the first argument")
-        return utils.FAILURE
-
-    parameters['TimeoutInMinutes'] = options.timeout
-
-    if options.enable_rollback:
-        parameters['DisableRollback'] = 'False'
-
-    templ_param = get_template_param(options)
-    if templ_param:
-        parameters.update(templ_param)
-    else:
-        logging.error('Please specify a template file or url')
-        return utils.FAILURE
-
-    c = get_client(options)
-    parameters.update(c.format_parameters(options))
-    result = c.create_stack(**parameters)
-    print result
-
-
-@utils.catch_error('update')
-def stack_update(options, arguments):
-    '''
-    Update an existing stack.
-
-    Usage: heat-cfn update <stack name> \\
-        [--template-file=<template file>|--template-url=<template URL>] \\
-        [options]
-
-    Stack Name: The name of the stack you wish to modify.
-
-    --template-file: Specify a local template file containing a valid
-                     stack description template.
-    --template-url:  Specify a URL pointing to a valid stack description
-                     template.
-
-    Options:
-        --parameters: A list of key/value pairs separated by ';'s used
-                      to specify allowed values in the template file.
-    '''
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Please specify the stack name you wish to update")
-        logging.error("as the first argument")
-        return utils.FAILURE
-
-    templ_param = get_template_param(options)
-    if templ_param:
-        parameters.update(templ_param)
-    else:
-        logging.error('Please specify a template file or url')
-        return utils.FAILURE
-
-    c = get_client(options)
-    parameters.update(c.format_parameters(options))
-    result = c.update_stack(**parameters)
-    print result
-
-
-@utils.catch_error('delete')
-def stack_delete(options, arguments):
-    '''
-    Delete an existing stack.  This shuts down all VMs associated with
-    the stack and (perhaps wrongly) also removes all events associated
-    with the given stack.
-
-    Usage: heat-cfn delete <stack name>
-    '''
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Please specify the stack name you wish to delete")
-        logging.error("as the first argument")
-        return utils.FAILURE
-
-    c = get_client(options)
-    result = c.delete_stack(**parameters)
-    print result
-
-
-@utils.catch_error('describe')
-def stack_describe(options, arguments):
-    '''
-    Describes an existing stack.
-
-    Usage: heat-cfn describe <stack name>
-    '''
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        logging.info("No stack name passed, getting results for ALL stacks")
-
-    c = get_client(options)
-    result = c.describe_stacks(**parameters)
-    print c.format_stack(result)
-
-
-@utils.catch_error('event-list')
-def stack_events_list(options, arguments):
-    '''
-    List events associated with the given stack.
-
-    Usage: heat-cfn event-list <stack name>
-    '''
-    parameters = {}
-    try:
-        parameters['StackName'] = arguments.pop(0)
-    except IndexError:
-        pass
-
-    c = get_client(options)
-    result = c.list_stack_events(**parameters)
-    print c.format_stack_event(result)
-
-
-@utils.catch_error('resource')
-def stack_resource_show(options, arguments):
-    '''
-    Display details of the specified resource.
-    '''
-    c = get_client(options)
-    try:
-        stack_name, resource_name = arguments
-    except ValueError:
-        print 'Enter stack name and logical resource id'
-        return
-
-    parameters = {
-        'StackName': stack_name,
-        'LogicalResourceId': resource_name,
-    }
-    result = c.describe_stack_resource(**parameters)
-    print c.format_stack_resource_detail(result)
-
-
-@utils.catch_error('resource-list')
-def stack_resources_list(options, arguments):
-    '''
-    Display summary of all resources in the specified stack.
-    '''
-    c = get_client(options)
-    try:
-        stack_name = arguments.pop(0)
-    except IndexError:
-        print 'Enter stack name'
-        return
-
-    parameters = {
-        'StackName': stack_name,
-    }
-    result = c.list_stack_resources(**parameters)
-    print c.format_stack_resource_summary(result)
-
-
-@utils.catch_error('resource-list-details')
-def stack_resources_list_details(options, arguments):
-    '''
-    Display details of resources in the specified stack.
-
-    - If stack name is specified, all associated resources are returned
-    - If physical resource ID is specified, all associated resources of the
-    stack the resource belongs to are returned
-    - You must specify stack name *or* physical resource ID
-    - You may optionally specify a Logical resource ID to filter the result
-    '''
-    usage = ('''Usage:
-%s resource-list-details stack_name [logical_resource_id]
-%s resource-list-details physical_resource_id [logical_resource_id]''' %
-             (scriptname, scriptname))
-
-    try:
-        name_or_pid = arguments.pop(0)
-    except IndexError:
-        logging.error("Must pass a stack_name or physical_resource_id")
-        print usage
-        return
-
-    logical_resource_id = arguments.pop(0) if arguments else None
-    parameters = {
-        'NameOrPid': name_or_pid,
-        'LogicalResourceId': logical_resource_id, }
-
-    c = get_client(options)
-    result = c.describe_stack_resources(**parameters)
-
-    if result:
-        print c.format_stack_resource(result)
-    else:
-        logging.error("Invalid stack_name, physical_resource_id " +
-                      "or logical_resource_id")
-        print usage
-
-
-@utils.catch_error('list')
-def stack_list(options, arguments):
-    '''
-    List all running stacks.
-
-    Usage: heat-cfn list
-    '''
-    c = get_client(options)
-    result = c.list_stacks()
-    print c.format_stack_summary(result)
-
-
-def get_client(options):
-    """
-    Returns a new client object to a heat server
-    specified by the --host and --port options
-    supplied to the CLI
-    Note options.host is ignored for heat-boto, host must be
-    set in your boto config via the cfn_region_endpoint option
-    """
-    return heat_client.get_client(host=options.host,
-                                  port=options.port,
-                                  username=options.username,
-                                  password=options.password,
-                                  tenant=options.tenant,
-                                  auth_url=options.auth_url,
-                                  auth_strategy=options.auth_strategy,
-                                  auth_token=options.auth_token,
-                                  region=options.region,
-                                  insecure=options.insecure)
-
-
-def create_options(parser):
-    """
-    Sets up the CLI and config-file options that may be
-    parsed and program commands.
-
-    :param parser: The option parser
-    """
-    parser.add_option('-v', '--verbose', default=False, action="store_true",
-                      help="Print more verbose output")
-    parser.add_option('-d', '--debug', default=False, action="store_true",
-                      help="Print more verbose output")
-    parser.add_option('-y', '--yes', default=False, action="store_true",
-                      help="Don't prompt for user input; assume the answer to "
-                           "every question is 'yes'.")
-    parser.add_option('-H', '--host', metavar="ADDRESS", default=None,
-                      help="Address of heat API host. "
-                           "Default: %default")
-    parser.add_option('-p', '--port', dest="port", metavar="PORT",
-                      type=int, default=config.DEFAULT_PORT,
-                      help="Port the heat API host listens on. "
-                           "Default: %default")
-    parser.add_option('-U', '--url', metavar="URL", default=None,
-                      help="URL of heat service. This option can be used "
-                           "to specify the hostname, port and protocol "
-                           "(http/https) of the heat server, for example "
-                           "-U https://localhost:" + str(config.DEFAULT_PORT) +
-                           "/v1 Default: No<F3>ne")
-    parser.add_option('-k', '--insecure', dest="insecure",
-                      default=False, action="store_true",
-                      help="Explicitly allow heat to perform \"insecure\" "
-                      "SSL (https) requests. The server's certificate will "
-                      "not be verified against any certificate authorities. "
-                      "This option should be used with caution.")
-    parser.add_option('-A', '--auth_token', dest="auth_token",
-                      metavar="TOKEN", default=None,
-                      help="Authentication token to use to identify the "
-                           "client to the heat server")
-    parser.add_option('-I', '--username', dest="username",
-                      metavar="USER", default=None,
-                      help="User name used to acquire an authentication "
-                           "token, defaults to env[OS_USERNAME]")
-    parser.add_option('-K', '--password', dest="password",
-                      metavar="PASSWORD", default=None,
-                      help="Password used to acquire an authentication "
-                           "token, defaults to env[OS_PASSWORD]")
-    parser.add_option('-T', '--tenant', dest="tenant",
-                      metavar="TENANT", default=None,
-                      help="Tenant name used for Keystone authentication, "
-                           "defaults to env[OS_TENANT_NAME]")
-    parser.add_option('-R', '--region', dest="region",
-                      metavar="REGION", default=None,
-                      help="Region name. When using keystone authentication "
-                      "version 2.0 or later this identifies the region "
-                      "name to use when selecting the service endpoint. A "
-                      "region name must be provided if more than one "
-                      "region endpoint is available")
-    parser.add_option('-N', '--auth_url', dest="auth_url",
-                      metavar="AUTH_URL", default=None,
-                      help="Authentication URL, "
-                           "defaults to env[OS_AUTH_URL]")
-    parser.add_option('-S', '--auth_strategy', dest="auth_strategy",
-                      metavar="STRATEGY", default=None,
-                      help="Authentication strategy (keystone or noauth)")
-
-    parser.add_option('-o', '--template-object',
-                      metavar="template_object", default=None,
-                      help="URL to retrieve template object (e.g from swift)")
-    parser.add_option('-u', '--template-url', metavar="template_url",
-                      default=None, help="URL of template. Default: None")
-    parser.add_option('-f', '--template-file', metavar="template_file",
-                      default=None, help="Path to the template. Default: None")
-    parser.add_option('-t', '--timeout', metavar="timeout",
-                      default='60',
-                      help='Stack creation timeout in minutes. Default: 60')
-
-    parser.add_option('-P', '--parameters', metavar="parameters", default=None,
-                      help="Parameter values used to create the stack.")
-
-    parser.add_option('-r', '--enable-rollback', dest="enable_rollback",
-                      default=False, action="store_true",
-                      help="Enable rollback on failure")
-
-
-def credentials_from_env():
-    return dict(username=os.getenv('OS_USERNAME'),
-                password=os.getenv('OS_PASSWORD'),
-                tenant=os.getenv('OS_TENANT_NAME'),
-                auth_url=os.getenv('OS_AUTH_URL'),
-                auth_strategy=os.getenv('OS_AUTH_STRATEGY'))
-
-
-def parse_options(parser, cli_args):
-    """
-    Returns the parsed CLI options, command to run and its arguments, merged
-    with any same-named options found in a configuration file
-
-    :param parser: The option parser
-    """
-    if not cli_args:
-        cli_args.append('-h')  # Show options in usage output...
-
-    (options, args) = parser.parse_args(cli_args)
-    env_opts = credentials_from_env()
-    for option, env_val in env_opts.items():
-        if not getattr(options, option):
-            setattr(options, option, env_val)
-
-    if scriptname == 'heat-boto':
-        if options.host is not None:
-            logging.error("Use boto.cfg or ~/.boto cfn_region_endpoint")
-            raise ValueError("--host option not supported by heat-boto")
-        if options.url is not None:
-            logging.error("Use boto.cfg or ~/.boto cfn_region_endpoint")
-            raise ValueError("--url option not supported by heat-boto")
-
-    if not (options.username and options.password) and not options.auth_token:
-        logging.error("Must specify credentials, " +
-                      "either username/password or token")
-        logging.error("See %s --help for options" % scriptname)
-        sys.exit(1)
-
-    if options.url is not None:
-        u = urlparse(options.url)
-        options.port = u.port
-        options.host = u.hostname
-
-    if not options.auth_strategy:
-        options.auth_strategy = 'noauth'
-
-    options.use_ssl = (options.url is not None and u.scheme == 'https')
-
-    # HACK(sirp): Make the parser available to the print_help method
-    # print_help is a command, so it only accepts (options, args); we could
-    # one-off have it take (parser, options, args), however, for now, I think
-    # this little hack will suffice
-    options.__parser = parser
-
-    if not args:
-        parser.print_usage()
-        sys.exit(0)
-
-    command_name = args.pop(0)
-    command = lookup_command(parser, command_name)
-
-    if options.debug:
-        logging.basicConfig(format='%(levelname)s:%(message)s',
-                            level=logging.DEBUG)
-        logging.debug("Debug level logging enabled")
-    elif options.verbose:
-        logging.basicConfig(format='%(levelname)s:%(message)s',
-                            level=logging.INFO)
-    else:
-        logging.basicConfig(format='%(levelname)s:%(message)s',
-                            level=logging.WARNING)
-
-    return (options, command, args)
-
-
-def print_help(options, args):
-    """
-    Print help specific to a command
-    """
-    parser = options.__parser
-
-    if not args:
-        parser.print_usage()
-
-    subst = {'prog': os.path.basename(sys.argv[0])}
-    docs = [lookup_command(parser, cmd).__doc__ % subst for cmd in args]
-    print '\n\n'.join(docs)
-
-
-def lookup_command(parser, command_name):
-    base_commands = {'help': print_help}
-
-    stack_commands = {'create': stack_create,
-                      'update': stack_update,
-                      'delete': stack_delete,
-                      'list': stack_list,
-                      'events_list': stack_events_list,  # DEPRECATED
-                      'event-list': stack_events_list,
-                      'resource': stack_resource_show,
-                      'resource-list': stack_resources_list,
-                      'resource-list-details': stack_resources_list_details,
-                      'validate': template_validate,
-                      'gettemplate': get_template,
-                      'estimate-template-cost': estimate_template_cost,
-                      'describe': stack_describe}
-
-    commands = {}
-    for command_set in (base_commands, stack_commands):
-        commands.update(command_set)
-
-    try:
-        command = commands[command_name]
-    except KeyError:
-        parser.print_usage()
-        sys.exit("Unknown command: %s" % command_name)
-
-    return command
-
-
-def main():
-    '''
-    '''
-    usage = """
-%prog <command> [options] [args]
-
-Commands:
-
-    help <command>  Output help for one of the commands below
-
-    create          Create the stack
-
-    delete          Delete the stack
-
-    describe        Describe the stack
-
-    update          Update the stack
-
-    list            List the user's stacks
-
-    gettemplate     Get the template
-
-    estimate-template-cost     Returns the estimated monthly cost of a template
-
-    validate        Validate a template
-
-    event-list      List events for a stack
-
-    resource        Describe the resource
-
-    resource-list   Show list of resources belonging to a stack
-
-    resource-list-details    Detailed view of resources belonging to a stack
-
-"""
-
-    version_string = version.version_string()
-    oparser = optparse.OptionParser(version=version_string,
-                                    usage=usage.strip())
-    create_options(oparser)
-    try:
-        (opts, cmd, args) = parse_options(oparser, sys.argv[1:])
-    except ValueError as ex:
-        logging.error("Error parsing options : %s" % str(ex))
-        sys.exit(1)
-
-    try:
-        start_time = time.time()
-        result = cmd(opts, args)
-        end_time = time.time()
-        logging.debug("Completed in %-0.4f sec." % (end_time - start_time))
-        sys.exit(result)
-    except (RuntimeError,
-            NotImplementedError,
-            exception.ClientConfigurationError) as ex:
-        oparser.print_usage()
-        logging.error("ERROR: %s" % ex)
-        sys.exit(1)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/bin/heat-watch b/bin/heat-watch
deleted file mode 100755 (executable)
index 21b9741..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-#    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.
-
-"""
-This is the administration program for heat-api-cloudwatch.
-It is simply a command-line interface for adding, modifying, and retrieving
-information about the cloudwatch alarms and metrics belonging to a user.
-It is a convenience application that talks to the heat Cloudwatch API server.
-"""
-
-import optparse
-import os
-import os.path
-import sys
-import time
-import logging
-
-# If ../heat/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
-                                   os.pardir,
-                                   os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'heat', '__init__.py')):
-    sys.path.insert(0, possible_topdir)
-
-scriptname = os.path.basename(sys.argv[0])
-
-from heat.openstack.common import gettextutils
-
-gettextutils.install('heat')
-
-from heat.cfn_client import boto_client_cloudwatch as heat_client
-from heat.version import version_info as version
-from heat.common import exception
-from heat.cfn_client import utils
-
-DEFAULT_PORT = 8003
-
-
-@utils.catch_error('alarm-describe')
-def alarm_describe(options, arguments):
-    '''
-    Describe detail for specified alarm, or all alarms
-    if no AlarmName is specified
-    '''
-    parameters = {}
-    try:
-        parameters['AlarmName'] = arguments.pop(0)
-    except IndexError:
-        logging.info("No AlarmName passed, getting results for ALL alarms")
-
-    c = heat_client.get_client(options.port)
-    result = c.describe_alarm(**parameters)
-    print c.format_metric_alarm(result)
-
-
-@utils.catch_error('alarm-set-state')
-def alarm_set_state(options, arguments):
-    '''
-    Temporarily set state for specified alarm
-    '''
-    usage = ('''Usage:
-             %s alarm-set-state AlarmName StateValue [StateReason]''' %
-             (scriptname))
-
-    parameters = {}
-    try:
-        parameters['AlarmName'] = arguments.pop(0)
-        parameters['StateValue'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Must specify AlarmName and StateValue")
-        print usage
-        print "StateValue must be one of %s, %s or %s" % (
-            heat_client.BotoCWClient.ALARM_STATES)
-        return utils.FAILURE
-    try:
-        parameters['StateReason'] = arguments.pop(0)
-    except IndexError:
-        parameters['StateReason'] = ""
-
-    # We don't handle attaching data to state via this cli tool (yet)
-    parameters['StateReasonData'] = None
-
-    c = heat_client.get_client(options.port)
-    result = c.set_alarm_state(**parameters)
-    print result
-
-
-@utils.catch_error('metric-list')
-def metric_list(options, arguments):
-    '''
-    List all metric data for a given metric (or all metrics if none specified)
-    '''
-    parameters = {}
-    try:
-        parameters['MetricName'] = arguments.pop(0)
-    except IndexError:
-        logging.info("No MetricName passed, getting results for ALL alarms")
-
-    c = heat_client.get_client(options.port)
-    result = c.list_metrics(**parameters)
-    print c.format_metric(result)
-
-
-@utils.catch_error('metric-put-data')
-def metric_put_data(options, arguments):
-    '''
-    Create a datapoint for a specified metric
-    '''
-    usage = ('''Usage:
-%s metric-put-data AlarmName Namespace MetricName Units MetricValue
-e.g
-%s metric-put-data HttpFailureAlarm system/linux ServiceFailure Count 1
-''' % (scriptname, scriptname))
-
-    # NOTE : we currently only support metric datapoints associated with a
-    # specific AlarmName, due to the current engine/db cloudwatch
-    # implementation, we should probably revisit this so we can support
-    # more generic metric data collection
-    parameters = {}
-    try:
-        parameters['AlarmName'] = arguments.pop(0)
-        parameters['Namespace'] = arguments.pop(0)
-        parameters['MetricName'] = arguments.pop(0)
-        parameters['MetricUnit'] = arguments.pop(0)
-        parameters['MetricValue'] = arguments.pop(0)
-    except IndexError:
-        logging.error("Please specify the alarm, metric, unit and value")
-        print usage
-        return utils.FAILURE
-
-    c = heat_client.get_client(options.port)
-    result = c.put_metric_data(**parameters)
-    print result
-
-
-def create_options(parser):
-    """
-    Sets up the CLI and config-file options that may be
-    parsed and program commands.
-
-    :param parser: The option parser
-    """
-    parser.add_option('-v', '--verbose', default=False, action="store_true",
-                      help="Print more verbose output")
-    parser.add_option('-d', '--debug', default=False, action="store_true",
-                      help="Print more verbose output")
-    parser.add_option('-p', '--port', dest="port", type=int,
-                      default=DEFAULT_PORT,
-                      help="Port the heat API host listens on. "
-                           "Default: %default")
-
-
-def parse_options(parser, cli_args):
-    """
-    Returns the parsed CLI options, command to run and its arguments, merged
-    with any same-named options found in a configuration file
-
-    :param parser: The option parser
-    """
-    if not cli_args:
-        cli_args.append('-h')  # Show options in usage output...
-
-    (options, args) = parser.parse_args(cli_args)
-
-    # HACK(sirp): Make the parser available to the print_help method
-    # print_help is a command, so it only accepts (options, args); we could
-    # one-off have it take (parser, options, args), however, for now, I think
-    # this little hack will suffice
-    options.__parser = parser
-
-    if not args:
-        parser.print_usage()
-        sys.exit(0)
-
-    command_name = args.pop(0)
-    command = lookup_command(parser, command_name)
-
-    if options.debug:
-        logging.basicConfig(format='%(levelname)s:%(message)s',
-                            level=logging.DEBUG)
-        logging.debug("Debug level logging enabled")
-    elif options.verbose:
-        logging.basicConfig(format='%(levelname)s:%(message)s',
-                            level=logging.INFO)
-    else:
-        logging.basicConfig(format='%(levelname)s:%(message)s',
-                            level=logging.WARNING)
-
-    return (options, command, args)
-
-
-def print_help(options, args):
-    """
-    Print help specific to a command
-    """
-    parser = options.__parser
-
-    if not args:
-        parser.print_usage()
-
-    subst = {'prog': os.path.basename(sys.argv[0])}
-    docs = [lookup_command(parser, cmd).__doc__ % subst for cmd in args]
-    print '\n\n'.join(docs)
-
-
-def lookup_command(parser, command_name):
-    base_commands = {'help': print_help}
-
-    watch_commands = {
-        'describe': alarm_describe,
-        'set-state': alarm_set_state,
-        'metric-list': metric_list,
-        'metric-put-data': metric_put_data}
-
-    commands = {}
-    for command_set in (base_commands, watch_commands):
-        commands.update(command_set)
-
-    try:
-        command = commands[command_name]
-    except KeyError:
-        parser.print_usage()
-        sys.exit("Unknown command: %s" % command_name)
-
-    return command
-
-
-def main():
-    '''
-    '''
-    usage = """
-%prog <command> [options] [args]
-
-Commands:
-
-    help <command>  Output help for one of the commands below
-
-    describe                    Describe a specified alarm (or all alarms)
-
-    set-state                   Temporarily set the state of an alarm
-
-    metric-list                 List data-points for specified metric
-
-    metric-put-data             Publish data-point for specified  metric
-
-"""
-    version_string = version.version_string()
-    oparser = optparse.OptionParser(version=version_string,
-                                    usage=usage.strip())
-    create_options(oparser)
-    (opts, cmd, args) = parse_options(oparser, sys.argv[1:])
-
-    try:
-        start_time = time.time()
-        result = cmd(opts, args)
-        end_time = time.time()
-        logging.debug("Completed in %-0.4f sec." % (end_time - start_time))
-        sys.exit(result)
-    except (RuntimeError,
-            NotImplementedError,
-            exception.ClientConfigurationError) as ex:
-        oparser.print_usage()
-        logging.error("ERROR: %s" % ex)
-        sys.exit(1)
-
-
-if __name__ == '__main__':
-    main()
index 4a115efc857f69b1545d4fcab02046ee43e580df..d30d58bb2fd039bd9aff614894fe7c2224375837 100644 (file)
@@ -222,12 +222,6 @@ man_pages = [
     ('man/heat-api-cloudwatch', 'heat-api-cloudwatch',
     u'CloudWatch alike API service to the heat project',
     [u'Heat Developers'], 1),
-    ('man/heat-boto', 'heat-boto',
-    u'Command line utility to run heat actions over the CloudFormation API',
-    [u'Heat Developers'], 1),
-    ('man/heat-cfn', 'heat-cfn',
-    u'Command line utility to run heat actions over the CloudFormation API',
-    [u'Heat Developers'], 1),
     ('man/heat-db-setup', 'heat-db-setup',
     u'Command line utility to setup the Heat database',
     [u'Heat Developers'], 1),
@@ -237,9 +231,6 @@ man_pages = [
     ('man/heat-keystone-setup', 'heat-keystone-setup',
     u'Script which sets up keystone for usage by Heat',
     [u'Heat Developers'], 1),
-    ('man/heat-watch', 'heat-watch',
-    u'Command line utility to run heat watch actions over the CloudWatch API',
-    [u'Heat Developers'], 1),
 ]
 
 # If true, show URL addresses after external links.
diff --git a/doc/source/man/heat-boto.rst b/doc/source/man/heat-boto.rst
deleted file mode 100644 (file)
index 7a1a605..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-=========
-heat-boto
-=========
-
-.. program:: heat-boto
-
-SYNOPSIS
-========
-
-``heat-boto [OPTIONS] COMMAND [COMMAND_OPTIONS]``
-
-DESCRIPTION
-===========
-heat-boto is a command-line utility for heat. It is a variant of the heat-cfn
-tool which uses the boto client library (instead of the heat CFN client
-library)
-
-The tool provides an interface for adding, modifying, and retrieving
-information about the stacks belonging to a user.  It is a convenience
-application that talks to the heat CloudFormation API.
-
-
-CONFIGURATION
-=============
-
-heat-watch uses the boto client library, and expects some configuration files
-to exist in your environment, see our wiki for an example configuration file:
-
-https://wiki.openstack.org/wiki/Heat/Using-Boto
-
-
-COMMANDS
-========
-
-``create``
-
-  Create stack as defined in template file
-
-``delete``
-
-  Delete specified stack
-
-``describe``
-
-  Provide detailed information about the specified stack, or if no arguments are given all stacks
-
-``estimate-template-cost``
-
-  Currently not implemented
-
-``event-list``
-
-  List events related to specified stacks, or if no arguments are given all stacks
-
-``gettemplate``
-
-  Get the template for a running stack
-
-``help``
-
-  Provide help/usage information
-
-``list``
-
-  List summary information for all stacks
-
-``resource``
-
-  List information about a specific resource
-
-``resource-list``
-
-  List all resources for a specified stack
-
-``resource-list-details``
-
-  List details of all resources for a specified stack or physical resource ID, optionally filtered by a logical resource ID
-
-``update``
-
-  Update a running stack with a modified template or template parameters - currently not implemented
-
-``validate``
-
-  Validate a template file syntax
-
-
-OPTIONS
-=======
-
-Note some options are marked as having no effect due to the common implementation with heat-cfn.
-These are options which work with heat-cfn, but not with heat-boto, in most cases the information
-should be specified via your boto configuration file instead.
-
-.. cmdoption:: -S, --auth_strategy
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -A, --auth_token
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -N, --auth_url
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -d, --debug
-
-  Enable verbose debug level output
-
-.. cmdoption:: -H, --host
-
-  Note, this option does not work for heat-boto due to limitations of the boto library
-  You should specify cfn_region_endpoint option in your boto config.
-
-.. cmdoption:: -k, --insecure
-
-  This option has no effect, is_secure should be specified in your boto config
-
-.. cmdoption:: -P, --parameters
-
-  Stack input parameters
-
-.. cmdoption:: -K, --password
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -p, --port
-
-  Specify the port to connect to for the heat API service
-
-.. cmdoption:: -R, --region
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -f, --template-file
-
-  Path to file containing the stack template
-
-.. cmdoption:: -u, --template-url
-
-  URL to stack template
-
-.. cmdoption:: -T, --tenant
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -t, --timeout
-
-  Stack creation timeout (default is 60 minutes)
-
-.. cmdoption:: -U, --url
-
-  This option has no effect, cfn_region_endpoint should be specified in your boto config
-
-.. cmdoption:: -I, --username
-
-  This option has no effect, credentials should be specified in your boto config
-
-.. cmdoption:: -v, --verbose
-
-  Enable verbose output
-
-.. cmdoption:: -y, --yes
-
-  Do not prompt for confirmation, assume yes
-
-
-EXAMPLES
-========
-  heat-boto -d create wordpress \\
-      --template-file=templates/WordPress_Single_Instance.template\\
-      --parameters="InstanceType=m1.xlarge;DBUsername=${USER};\\
-      DBPassword=verybadpass;KeyName=${USER}_key"
-
-  heat-boto list
-
-  heat-boto describe wordpress
-
-  heat-boto resource-list wordpress
-
-  heat-boto resource-list-details wordpress
-
-  heat-boto resource-list-details wordpress WikiDatabase
-
-  heat-boto resource wordpress WikiDatabase
-
-  heat-boto event-list
-
-  heat-boto delete wordpress
-
-BUGS
-====
-Heat bugs are managed through Launchpad <https://launchpad.net/heat>
diff --git a/doc/source/man/heat-cfn.rst b/doc/source/man/heat-cfn.rst
deleted file mode 100644 (file)
index 602048f..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-========
-heat-cfn
-========
-
-.. program:: heat-cfn
-
-SYNOPSIS
-========
-
-``heat-cfn [OPTIONS] COMMAND [COMMAND_OPTIONS]``
-
-DESCRIPTION
-===========
-heat-cfn is a command-line utility for heat. It is simply an
-interface for adding, modifying, and retrieving information about the stacks
-belonging to a user.  It is a convenience application that talks to the heat
-CloudFormation API compatable server.
-
-
-CONFIGURATION
-=============
-
-heat-cfn uses keystone authentication, and expects some variables to be
-set in your environment, without these heat will not be able to establish
-an authenticated connection with the heat API server.
-
-Example:
-
-export ADMIN_TOKEN=<keystone admin token>
-
-export OS_USERNAME=admin
-
-export OS_PASSWORD=verybadpass
-
-export OS_TENANT_NAME=admin
-
-export OS_AUTH_URL=http://127.0.0.1:5000/v2.0/
-
-export OS_AUTH_STRATEGY=keystone
-
-
-
-COMMANDS
-========
-
-``create``
-
-  Create stack as defined in template file
-
-``delete``
-
-  Delete specified stack
-
-``describe``
-
-  Provide detailed information about the specified stack, or if no arguments are given all stacks
-
-``estimate-template-cost``
-
-  Currently not implemented
-
-``event-list``
-
-  List events related to specified stacks, or if no arguments are given all stacks
-
-``gettemplate``
-
-  Get the template for a running stack
-
-``help``
-
-  Provide help/usage information
-
-``list``
-
-  List summary information for all stacks
-
-``resource``
-
-  List information about a specific resource
-
-``resource-list``
-
-  List all resources for a specified stack
-
-``resource-list-details``
-
-  List details of all resources for a specified stack or physical resource ID, optionally filtered by a logical resource ID
-
-``update``
-
-  Update a running stack with a modified template or template parameters - currently not implemented
-
-``validate``
-
-  Validate a template file syntax
-
-
-OPTIONS
-=======
-
-.. cmdoption:: -S, --auth_strategy
-
-  Authentication strategy
-
-.. cmdoption:: -A, --auth_token
-
-  Authentication token to use to identify the client to the heat server
-
-.. cmdoption:: -N, --auth_url
-
-  Authentication URL for keystone authentication
-
-.. cmdoption:: -d, --debug
-
-  Enable verbose debug level output
-
-.. cmdoption:: -H, --host
-
-  Specify the hostname running the heat API service
-
-.. cmdoption:: -k, --insecure
-
-  Use plain HTTP instead of HTTPS
-
-.. cmdoption:: -P, --parameters
-
-  Stack input parameters
-
-.. cmdoption:: -K, --password
-
-  Password used to acquire an authentication token
-
-.. cmdoption:: -p, --port
-
-  Specify the port to connect to for the heat API service
-
-.. cmdoption:: -R, --region
-
-  Region name. When using keystone authentication "version 2.0 or later this identifies the region
-
-.. cmdoption:: -f, --template-file
-
-  Path to file containing the stack template
-
-.. cmdoption:: -u, --template-url
-
-  URL to stack template
-
-.. cmdoption:: -T, --tenant
-
-  Tenant name used for Keystone authentication
-
-.. cmdoption:: -t, --timeout
-
-  Stack creation timeout (default is 60 minutes)
-
-.. cmdoption:: -U, --url
-
-  URL of heat service
-
-.. cmdoption:: -I, --username
-
-  User name used to acquire an authentication token
-
-.. cmdoption:: -v, --verbose
-
-  Enable verbose output
-
-.. cmdoption:: -y, --yes
-
-  Do not prompt for confirmation, assume yes
-
-
-EXAMPLES
-========
-  heat-cfn -d create wordpress --template-
-  file=templates/WordPress_Single_Instance.template
-  --parameters="InstanceType=m1.xlarge;DBUsername=${USER};DBPassword=verybadpass;KeyName=${USER}_key"
-
-  heat-cfn list
-
-  heat-cfn describe wordpress
-
-  heat-cfn resource-list wordpress
-
-  heat-cfn resource-list-details wordpress
-
-  heat-cfn resource-list-details wordpress WikiDatabase
-
-  heat-cfn resource wordpress WikiDatabase
-
-  heat-cfn event-list
-
-  heat-cfn delete wordpress
-
-BUGS
-====
-Heat bugs are managed through Launchpad <https://launchpad.net/heat>
\ No newline at end of file
diff --git a/doc/source/man/heat-watch.rst b/doc/source/man/heat-watch.rst
deleted file mode 100644 (file)
index c37a5f7..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-==========
-heat-watch
-==========
-
-.. program:: heat-watch
-
-
-SYNOPSIS
-========
-
-``heat-watch [OPTIONS] COMMAND [COMMAND_OPTIONS]``
-
-
-DESCRIPTION
-===========
-heat-watch is a command-line utility for heat-api-cloudwatch.
-It allows manipulation of the watch alarms and metric data via the heat
-cloudwatch API, so this service must be running and accessibe on the host
-specified in your boto config (cloudwatch_region_endpoint)
-
-
-CONFIGURATION
-=============
-
-heat-watch uses the boto client library, and expects some configuration files
-to exist in your environment, see our wiki for an example configuration file:
-
-https://wiki.openstack.org/wiki/Heat/Using-Boto
-
-
-COMMANDS
-========
-
-``describe``
-
-  Provide detailed information about the specified watch rule, or if no arguments are given all watch rules
-
-``set-state``
-
-  Temporarily set the state of a watch rule
-
-``metric-list``
-
-  List data-points for a specified metric
-
-``metric-put-data``
-
-  Publish data-point for specified  metric
-
-  Note the metric must be associated with a CloudWatch Alarm (specified in a heat stack template), publishing arbitrary metric data is not supported.
-
-``help``
-
-  Provide help/usage information on each command
-
-
-OPTIONS
-=======
-
-.. cmdoption:: --version
-
-  show program version number and exit
-
-.. cmdoption:: -h, --help
-
-  show this help message and exit
-
-.. cmdoption:: -v, --verbose
-
-  Print more verbose output
-
-.. cmdoption:: -d, --debug
-
-  Print debug output
-
-.. cmdoption:: -p, --port
-
-  Specify port the heat CW API host listens on. Default: 8003
-
-
-EXAMPLES
-========
-
-  heat-watch describe
-
-  heat-watch metric-list
-
-  heat-watch metric-put-data HttpFailureAlarm system/linux ServiceFailure Count 1
-
-  heat-watch set-state HttpFailureAlarm ALARM
-
-
-BUGS
-====
-Heat bugs are managed through Launchpad <https://launchpad.net/heat>
index c19c003fcd4ac181371f355d566f3c26d7ef05b2..9de280134f5e09d1dfb6049f28f86011e3c0f2b9 100644 (file)
@@ -21,8 +21,5 @@ Heat utilities
 .. toctree::
    :maxdepth: 2
 
-   heat-cfn
-   heat-boto
-   heat-watch
    heat-db-setup
    heat-keystone-setup
diff --git a/etc/bash_completion.d/heat-cfn b/etc/bash_completion.d/heat-cfn
deleted file mode 100644 (file)
index a4ed068..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-_heat()
-{
-    local cur prev opts
-    COMPREPLY=()
-    cur="${COMP_WORDS[COMP_CWORD]}"
-    prev="${COMP_WORDS[COMP_CWORD-1]}"
-
-    if [[ ${cur} == -* ]]; then
-        opts=$(heat-cfn --help | grep -A100 "^Options" | sed -r "s/^[[:space:]]*-[[:alpha:]]([[:space:]][[:alpha:]_]*,|,)[[:space:]]//" | cut -d "=" -f1 | grep "^--" | awk '{print $1}')
-        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
-        return 0
-    fi
-
-    if [[ ${#COMP_WORDS[@]} -gt 2 ]]; then
-        return 0
-    else
-        cmds=$(heat-cfn help  | awk '{print $1}' | egrep -v "^(Usage|Commands|$)")
-        COMPREPLY=( $(compgen -W "${cmds}" -- ${cur}) )
-        return 0
-    fi
-}
-complete -F _heat heat-cfn
diff --git a/etc/boto.cfg b/etc/boto.cfg
deleted file mode 100644 (file)
index 06ee348..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#[Credentials]
-# AWS credentials, from keystone ec2-credentials-list
-# Note this section should only be uncommented for per-user
-# boto config files, copy this file to ~/.boto
-# Alternatively the credentials can be passed into the boto
-# client at constructor-time in your code
-#aws_access_key_id = YOUR_KEY
-#aws_secret_access_key = YOUR_SECKEY
-
-[Boto]
-# Make boto output verbose debugging information
-debug = 0
-
-# Disable https connections
-is_secure = 0
-
-# Override the default AWS endpoint to connect to heat on localhost
-cfn_region_name = heat
-cfn_region_endpoint = 127.0.0.1
-
-cloudwatch_region_name = heat
-cloudwatch_region_endpoint = 127.0.0.1
-
-# Set the client retries to 1, or errors connecting to heat repeat
-# which is not useful when debugging API issues
-num_retries = 1
diff --git a/heat/cfn_client/__init__.py b/heat/cfn_client/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/heat/cfn_client/boto_client.py b/heat/cfn_client/boto_client.py
deleted file mode 100644 (file)
index 6229d33..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    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.
-
-"""
-Client implementation based on the boto AWS client library
-"""
-
-import sys
-
-from heat.openstack.common import log as logging
-logger = logging.getLogger(__name__)
-
-from boto.cloudformation import CloudFormationConnection
-
-
-class BotoClient(CloudFormationConnection):
-    '''
-    Wrapper class for boto CloudFormationConnection class
-    '''
-
-    def list_stacks(self, **kwargs):
-        return super(BotoClient, self).list_stacks()
-
-    def describe_stacks(self, **kwargs):
-        try:
-            stack_name = kwargs['StackName']
-        except KeyError:
-            stack_name = None
-        return super(BotoClient, self).describe_stacks(stack_name)
-
-    def create_stack(self, **kwargs):
-        args = {'disable_rollback': True}
-        if str(kwargs.get('DisableRollback', '')).lower() == 'false':
-            args['disable_rollback'] = False
-
-        if 'TimeoutInMinutes' in kwargs:
-            try:
-                timeout = int(kwargs['TimeoutInMinutes'])
-            except ValueError:
-                logger.error("Invalid timeout %s" % kwargs['TimeoutInMinutes'])
-                return
-            else:
-                args['timeout_in_minutes'] = timeout
-
-        if 'TemplateUrl' in kwargs:
-            return super(BotoClient, self).create_stack(
-                kwargs['StackName'],
-                template_url=kwargs['TemplateUrl'],
-                parameters=kwargs['Parameters'],
-                **args)
-        elif 'TemplateBody' in kwargs:
-            return super(BotoClient, self).create_stack(
-                kwargs['StackName'],
-                template_body=kwargs['TemplateBody'],
-                parameters=kwargs['Parameters'],
-                **args)
-        else:
-            logger.error("Must specify TemplateUrl or TemplateBody!")
-
-    def update_stack(self, **kwargs):
-        if 'TemplateUrl' in kwargs:
-            return super(BotoClient, self).update_stack(
-                kwargs['StackName'],
-                template_url=kwargs['TemplateUrl'],
-                parameters=kwargs['Parameters'])
-        elif 'TemplateBody' in kwargs:
-            return super(BotoClient, self).update_stack(
-                kwargs['StackName'],
-                template_body=kwargs['TemplateBody'],
-                parameters=kwargs['Parameters'])
-        else:
-            logger.error("Must specify TemplateUrl or TemplateBody!")
-
-    def delete_stack(self, **kwargs):
-        return super(BotoClient, self).delete_stack(kwargs['StackName'])
-
-    def list_stack_events(self, **kwargs):
-        return super(BotoClient, self).describe_stack_events(
-            kwargs['StackName'])
-
-    def describe_stack_resource(self, **kwargs):
-        return super(BotoClient, self).describe_stack_resource(
-            kwargs['StackName'], kwargs['LogicalResourceId'])
-
-    def describe_stack_resources(self, **kwargs):
-        # Check if this is a StackName, if not assume it's a physical res ID
-        # Note this is slower for the common case, which is probably StackName
-        # than just doing a try/catch over the StackName case then retrying
-        # on failure with kwargs['NameOrPid'] as the physical resource ID,
-        # however boto spews errors when raising an exception so we can't
-        list_stacks = self.list_stacks()
-        stack_names = [s.stack_name for s in list_stacks]
-        if kwargs['NameOrPid'] in stack_names:
-            logger.debug("Looking up resources for StackName:%s" %
-                         kwargs['NameOrPid'])
-            return super(BotoClient, self).describe_stack_resources(
-                stack_name_or_id=kwargs['NameOrPid'],
-                logical_resource_id=kwargs['LogicalResourceId'])
-        else:
-            logger.debug("Looking up resources for PhysicalResourceId:%s" %
-                         kwargs['NameOrPid'])
-            return super(BotoClient, self).describe_stack_resources(
-                stack_name_or_id=None,
-                logical_resource_id=kwargs['LogicalResourceId'],
-                physical_resource_id=kwargs['NameOrPid'])
-
-    def list_stack_resources(self, **kwargs):
-        return super(BotoClient, self).list_stack_resources(
-            kwargs['StackName'])
-
-    def validate_template(self, **kwargs):
-        if 'TemplateUrl' in kwargs:
-            return super(BotoClient, self).validate_template(
-                template_url=kwargs['TemplateUrl'])
-        elif 'TemplateBody' in kwargs:
-            return super(BotoClient, self).validate_template(
-                template_body=kwargs['TemplateBody'])
-        else:
-            logger.error("Must specify TemplateUrl or TemplateBody!")
-
-    def get_template(self, **kwargs):
-        return super(BotoClient, self).get_template(kwargs['StackName'])
-
-    def estimate_template_cost(self, **kwargs):
-        if 'TemplateUrl' in kwargs:
-            return super(BotoClient, self).estimate_template_cost(
-                kwargs['StackName'],
-                template_url=kwargs['TemplateUrl'],
-                parameters=kwargs['Parameters'])
-        elif 'TemplateBody' in kwargs:
-            return super(BotoClient, self).estimate_template_cost(
-                kwargs['StackName'],
-                template_body=kwargs['TemplateBody'],
-                parameters=kwargs['Parameters'])
-        else:
-            logger.error("Must specify TemplateUrl or TemplateBody!")
-
-    def format_stack_event(self, events):
-        '''
-        Return string formatted representation of
-        boto.cloudformation.stack.StackEvent objects
-        '''
-        ret = []
-        for event in events:
-            ret.append("EventId : %s" % event.event_id)
-            ret.append("LogicalResourceId : %s" % event.logical_resource_id)
-            ret.append("PhysicalResourceId : %s" % event.physical_resource_id)
-            ret.append("ResourceProperties : %s" % event.resource_properties)
-            ret.append("ResourceStatus : %s" % event.resource_status)
-            ret.append("ResourceStatusReason : %s" %
-                       event.resource_status_reason)
-            ret.append("ResourceType : %s" % event.resource_type)
-            ret.append("StackId : %s" % event.stack_id)
-            ret.append("StackName : %s" % event.stack_name)
-            ret.append("Timestamp : %s" % event.timestamp)
-            ret.append("--")
-        return '\n'.join(ret)
-
-    def format_stack(self, stacks):
-        '''
-        Return string formatted representation of
-        boto.cloudformation.stack.Stack objects
-        '''
-        ret = []
-        for s in stacks:
-            ret.append("Capabilities : %s" % s.capabilities)
-            ret.append("CreationTime : %s" % s.creation_time)
-            ret.append("Description : %s" % s.description)
-            ret.append("DisableRollback : %s" % s.disable_rollback)
-            ret.append("NotificationARNs : %s" % s.notification_arns)
-            ret.append("Outputs : %s" % s.outputs)
-            ret.append("Parameters : %s" % s.parameters)
-            ret.append("StackId : %s" % s.stack_id)
-            ret.append("StackName : %s" % s.stack_name)
-            ret.append("StackStatus : %s" % s.stack_status)
-            ret.append("StackStatusReason : %s" % s.stack_status_reason)
-            ret.append("TimeoutInMinutes : %s" % s.timeout_in_minutes)
-            ret.append("--")
-        return '\n'.join(ret)
-
-    def format_stack_resource(self, resources):
-        '''
-        Return string formatted representation of
-        boto.cloudformation.stack.StackResource objects
-        '''
-        ret = []
-        for res in resources:
-            ret.append("LogicalResourceId : %s" % res.logical_resource_id)
-            ret.append("PhysicalResourceId : %s" % res.physical_resource_id)
-            ret.append("ResourceStatus : %s" % res.resource_status)
-            ret.append("ResourceStatusReason : %s" %
-                       res.resource_status_reason)
-            ret.append("ResourceType : %s" % res.resource_type)
-            ret.append("StackId : %s" % res.stack_id)
-            ret.append("StackName : %s" % res.stack_name)
-            ret.append("Timestamp : %s" % res.timestamp)
-            ret.append("--")
-        return '\n'.join(ret)
-
-    def format_stack_resource_summary(self, resources):
-        '''
-        Return string formatted representation of
-        boto.cloudformation.stack.StackResourceSummary objects
-        '''
-        ret = []
-        for res in resources:
-            ret.append("LastUpdatedTimestamp : %s" %
-                       res.last_updated_timestamp)
-            ret.append("LogicalResourceId : %s" % res.logical_resource_id)
-            ret.append("PhysicalResourceId : %s" % res.physical_resource_id)
-            ret.append("ResourceStatus : %s" % res.resource_status)
-            ret.append("ResourceStatusReason : %s" %
-                       res.resource_status_reason)
-            ret.append("ResourceType : %s" % res.resource_type)
-            ret.append("--")
-        return '\n'.join(ret)
-
-    def format_stack_resource_detail(self, res):
-        '''
-        Print response from describe_stack_resource call
-
-        Note pending upstream patch will make this response a
-        boto.cloudformation.stack.StackResourceDetail object
-        which aligns better with all the existing calls
-        see https://github.com/boto/boto/pull/857
-
-        For now, we format the dict response as a workaround
-        '''
-        resource_detail = res['DescribeStackResourceResponse'][
-            'DescribeStackResourceResult']['StackResourceDetail']
-        ret = []
-        for key in resource_detail:
-            ret.append("%s : %s" % (key, resource_detail[key]))
-        return '\n'.join(ret)
-
-    def format_stack_summary(self, summaries):
-        '''
-        Return string formatted representation of
-        boto.cloudformation.stack.StackSummary objects
-        '''
-        ret = []
-        for s in summaries:
-            ret.append("StackId : %s" % s.stack_id)
-            ret.append("StackName : %s" % s.stack_name)
-            ret.append("CreationTime : %s" % s.creation_time)
-            ret.append("StackStatus : %s" % s.stack_status)
-            ret.append("TemplateDescription : %s" % s.template_description)
-            ret.append("--")
-        return '\n'.join(ret)
-
-    def format_template(self, template):
-        '''
-        String formatted representation of
-        boto.cloudformation.template.Template object
-        '''
-        ret = []
-        ret.append("Description : %s" % template.description)
-        for p in template.template_parameters:
-            ret.append("Parameter : ")
-            ret.append("  NoEcho : %s" % p.no_echo)
-            ret.append("  Description : %s" % p.description)
-            ret.append("  ParameterKey : %s" % p.parameter_key)
-        ret.append("--")
-        return '\n'.join(ret)
-
-    def format_parameters(self, options):
-        '''
-        Returns a dict containing list-of-tuple format
-        as expected by boto for request parameters
-        '''
-        parameters = {}
-        params = []
-        if options.parameters:
-            for p in options.parameters.split(';'):
-                (n, v) = p.split('=')
-                params.append((n, v))
-        parameters['Parameters'] = params
-        return parameters
-
-
-def get_client(host, port=None, username=None,
-               password=None, tenant=None,
-               auth_url=None, auth_strategy=None,
-               auth_token=None, region=None,
-               is_silent_upload=False, insecure=True,
-               aws_access_key=None, aws_secret_key=None):
-
-    """
-    Returns a new boto Cloudformation client connection to a heat server
-    """
-
-    # Note we pass None/None for the keys by default
-    # This means boto reads /etc/boto.cfg, or ~/.boto
-    # set is_secure=0 in the config to disable https
-    cloudformation = BotoClient(aws_access_key_id=aws_access_key,
-                                aws_secret_access_key=aws_secret_key,
-                                port=port,
-                                path="/v1")
-    if cloudformation:
-        logger.debug("Got CF connection object OK")
-    else:
-        logger.error("Error establishing Cloudformation connection!")
-        sys.exit(1)
-
-    return cloudformation
diff --git a/heat/cfn_client/boto_client_cloudwatch.py b/heat/cfn_client/boto_client_cloudwatch.py
deleted file mode 100644 (file)
index ed72b2d..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    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.
-
-"""
-Client implementation based on the boto AWS client library
-"""
-
-import sys
-
-from heat.openstack.common import log as logging
-logger = logging.getLogger(__name__)
-
-from boto.ec2.cloudwatch import CloudWatchConnection
-
-
-class BotoCWClient(CloudWatchConnection):
-    '''
-    Wrapper class for boto CloudWatchConnection class
-    '''
-    # TODO(unknown) : These should probably go in the CW API and be imported
-    DEFAULT_NAMESPACE = "heat/unknown"
-    METRIC_UNITS = ("Seconds", "Microseconds", "Milliseconds", "Bytes",
-                    "Kilobytes", "Megabytes", "Gigabytes", "Terabytes",
-                    "Bits", "Kilobits", "Megabits", "Gigabits", "Terabits",
-                    "Percent", "Count", "Bytes/Second", "Kilobytes/Second",
-                    "Megabytes/Second", "Gigabytes/Second", "Terabytes/Second",
-                    "Bits/Second", "Kilobits/Second", "Megabits/Second",
-                    "Gigabits/Second", "Terabits/Second", "Count/Second", None)
-    METRIC_COMPARISONS = (">=", ">", "<", "<=")
-    ALARM_STATES = ("OK", "ALARM", "INSUFFICIENT_DATA")
-    METRIC_STATISTICS = ("Average", "Sum", "SampleCount", "Maximum", "Minimum")
-
-    # Note, several of these boto calls take a list of alarm names, so
-    # we could easily handle multiple alarms per-action, but in the
-    # interests of keeping the client simple, we just handle one 'AlarmName'
-
-    def describe_alarm(self, **kwargs):
-        # If no AlarmName specified, we pass None, which returns
-        # results for ALL alarms
-        try:
-            name = kwargs['AlarmName']
-        except KeyError:
-            name = None
-        return super(BotoCWClient, self).describe_alarms(
-            alarm_names=[name])
-
-    def list_metrics(self, **kwargs):
-        # list_metrics returns non-null index in next_token if there
-        # are more than 500 metric results, in which case we have to
-        # re-read with the token to get the next batch of results
-        #
-        # Also note that we can do more advanced filtering by dimension
-        # and/or namespace, but for simplicity we only filter by
-        # MetricName for the time being
-        try:
-            name = kwargs['MetricName']
-        except KeyError:
-            name = None
-
-        results = []
-        token = None
-        while True:
-            results.append(super(BotoCWClient, self).list_metrics(
-                           next_token=token,
-                           dimensions=None,
-                           metric_name=name,
-                           namespace=None))
-            if not token:
-                break
-
-        return results
-
-    def put_metric_data(self, **kwargs):
-        '''
-        Publish metric data points to CloudWatch
-        '''
-        try:
-            metric_name = kwargs['MetricName']
-            metric_unit = kwargs['MetricUnit']
-            metric_value = kwargs['MetricValue']
-            metric_namespace = kwargs['Namespace']
-        except KeyError:
-            logger.error("Must pass MetricName, MetricUnit, " +
-                         "Namespace, MetricValue!")
-            return
-
-        try:
-            metric_unit = kwargs['MetricUnit']
-        except KeyError:
-            metric_unit = None
-
-        # If we're passed AlarmName, we attach it to the metric
-        # as a dimension
-        try:
-            metric_dims = [{'AlarmName': kwargs['AlarmName']}]
-        except KeyError:
-            metric_dims = []
-
-        if metric_unit not in self.METRIC_UNITS:
-            logger.error("MetricUnit not an allowed value")
-            logger.error("MetricUnit must be one of %s" % self.METRIC_UNITS)
-            return
-
-        return super(BotoCWClient, self).put_metric_data(
-            namespace=metric_namespace,
-            name=metric_name,
-            value=metric_value,
-            timestamp=None,  # This means use "now" in the engine
-            unit=metric_unit,
-            dimensions=metric_dims,
-            statistics=None)
-
-    def set_alarm_state(self, **kwargs):
-        return super(BotoCWClient, self).set_alarm_state(
-            alarm_name=kwargs['AlarmName'],
-            state_reason=kwargs['StateReason'],
-            state_value=kwargs['StateValue'],
-            state_reason_data=kwargs['StateReasonData'])
-
-    def format_metric_alarm(self, alarms):
-        '''
-        Return string formatted representation of
-        boto.ec2.cloudwatch.alarm.MetricAlarm objects
-        '''
-        ret = []
-        for s in alarms:
-            ret.append("AlarmName : %s" % s.name)
-            ret.append("AlarmDescription : %s" % s.description)
-            ret.append("ActionsEnabled : %s" % s.actions_enabled)
-            ret.append("AlarmActions : %s" % s.alarm_actions)
-            ret.append("AlarmArn : %s" % s.alarm_arn)
-            ret.append("AlarmConfigurationUpdatedTimestamp : %s" %
-                       s.last_updated)
-            ret.append("ComparisonOperator : %s" % s.comparison)
-            ret.append("Dimensions : %s" % s.dimensions)
-            ret.append("EvaluationPeriods : %s" % s.evaluation_periods)
-            ret.append("InsufficientDataActions : %s" %
-                       s.insufficient_data_actions)
-            ret.append("MetricName : %s" % s.metric)
-            ret.append("Namespace : %s" % s.namespace)
-            ret.append("OKActions : %s" % s.ok_actions)
-            ret.append("Period : %s" % s.period)
-            ret.append("StateReason : %s" % s.state_reason)
-            ret.append("StateUpdatedTimestamp : %s" %
-                       s.last_updated)
-            ret.append("StateValue : %s" % s.state_value)
-            ret.append("Statistic : %s" % s.statistic)
-            ret.append("Threshold : %s" % s.threshold)
-            ret.append("Unit : %s" % s.unit)
-            ret.append("--")
-        return '\n'.join(ret)
-
-    def format_metric(self, metrics):
-        '''
-        Return string formatted representation of
-        boto.ec2.cloudwatch.metric.Metric objects
-        '''
-        # Boto appears to return metrics as a list-inside-a-list
-        # probably a bug in boto, but work around here
-        if len(metrics) == 1:
-            metlist = metrics[0]
-        elif len(metrics) == 0:
-            metlist = []
-        else:
-            # Shouldn't get here, unless boto gets fixed..
-            logger.error("Unexpected metric list-of-list length (boto fixed?)")
-            return "ERROR\n--"
-
-        ret = []
-        for m in metlist:
-                ret.append("MetricName : %s" % m.name)
-                ret.append("Namespace  : %s" % m.namespace)
-                ret.append("Dimensions : %s" % m.dimensions)
-                ret.append("--")
-        return '\n'.join(ret)
-
-
-def get_client(port=None, aws_access_key=None, aws_secret_key=None):
-    """
-    Returns a new boto CloudWatch client connection to a heat server
-    Note : Configuration goes in /etc/boto.cfg, not via arguments
-    """
-
-    # Note we pass None/None for the keys so boto reads /etc/boto.cfg
-    # Also note is_secure is defaulted to False as HTTPS connections
-    # don't seem to work atm, FIXME
-    cloudwatch = BotoCWClient(aws_access_key_id=aws_access_key,
-                              aws_secret_access_key=aws_secret_key,
-                              is_secure=False,
-                              port=port,
-                              path="/v1")
-    if cloudwatch:
-        logger.debug("Got CW connection object OK")
-    else:
-        logger.error("Error establishing CloudWatch connection!")
-        sys.exit(1)
-
-    return cloudwatch
diff --git a/heat/cfn_client/client.py b/heat/cfn_client/client.py
deleted file mode 100644 (file)
index 000f743..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    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.
-
-"""
-Client classes for callers of a heat system
-"""
-
-from lxml import etree
-from heat.common import client as base_client
-from heat.common import exception
-
-from heat.openstack.common import log as logging
-
-logger = logging.getLogger(__name__)
-
-
-SUPPORTED_PARAMS = ('StackName', 'TemplateBody', 'TemplateUrl',
-                    'NotificationARNs', 'Parameters', 'Version',
-                    'SignatureVersion', 'Timestamp', 'AWSAccessKeyId',
-                    'Signature', 'TimeoutInMinutes', 'DisableRollback',
-                    'LogicalResourceId', 'PhysicalResourceId', 'NextToken',
-                    )
-
-
-class V1Client(base_client.BaseClient):
-
-    """Main client class for accessing heat resources."""
-
-    DEFAULT_DOC_ROOT = "/v1"
-
-    def _insert_common_parameters(self, params):
-        params['Version'] = '2010-05-15'
-        params['SignatureVersion'] = '2'
-        params['SignatureMethod'] = 'HmacSHA256'
-
-    def stack_request(self, action, method, **kwargs):
-        params = self._extract_params(kwargs, SUPPORTED_PARAMS)
-        self._insert_common_parameters(params)
-        params['Action'] = action
-        headers = {'X-Auth-User': self.creds['username'],
-                   'X-Auth-Key': self.creds['password']}
-
-        res = self.do_request(method, "/", params=params, headers=headers)
-        doc = etree.fromstring(res.read())
-        return etree.tostring(doc, pretty_print=True)
-
-    def list_stacks(self, **kwargs):
-        return self.stack_request("ListStacks", "GET", **kwargs)
-
-    def describe_stacks(self, **kwargs):
-        return self.stack_request("DescribeStacks", "GET", **kwargs)
-
-    def create_stack(self, **kwargs):
-        return self.stack_request("CreateStack", "POST", **kwargs)
-
-    def update_stack(self, **kwargs):
-        return self.stack_request("UpdateStack", "POST", **kwargs)
-
-    def delete_stack(self, **kwargs):
-        return self.stack_request("DeleteStack", "GET", **kwargs)
-
-    def list_stack_events(self, **kwargs):
-        return self.stack_request("DescribeStackEvents", "GET", **kwargs)
-
-    def describe_stack_resource(self, **kwargs):
-        return self.stack_request("DescribeStackResource", "GET", **kwargs)
-
-    def describe_stack_resources(self, **kwargs):
-        for lookup_key in ['StackName', 'PhysicalResourceId']:
-            lookup_value = kwargs['NameOrPid']
-            parameters = {
-                lookup_key: lookup_value,
-                'LogicalResourceId': kwargs['LogicalResourceId']}
-            try:
-                result = self.stack_request("DescribeStackResources", "GET",
-                                            **parameters)
-            except Exception:
-                logger.debug("Failed to lookup resource details with key %s:%s"
-                             % (lookup_key, lookup_value))
-            else:
-                logger.debug("Got lookup resource details with key %s:%s" %
-                             (lookup_key, lookup_value))
-                return result
-
-    def list_stack_resources(self, **kwargs):
-        return self.stack_request("ListStackResources", "GET", **kwargs)
-
-    def validate_template(self, **kwargs):
-        return self.stack_request("ValidateTemplate", "GET", **kwargs)
-
-    def get_template(self, **kwargs):
-        return self.stack_request("GetTemplate", "GET", **kwargs)
-
-    def estimate_template_cost(self, **kwargs):
-        return self.stack_request("EstimateTemplateCost", "GET", **kwargs)
-
-    # Dummy print functions for alignment with the boto-based client
-    # which has to extract class fields for printing, we could also
-    # align output format here by decoding the XML/JSON
-    def format_stack_event(self, event):
-        return str(event)
-
-    def format_stack(self, stack):
-        return str(stack)
-
-    def format_stack_resource(self, res):
-        return str(res)
-
-    def format_stack_resource_summary(self, res):
-        return str(res)
-
-    def format_stack_summary(self, summary):
-        return str(summary)
-
-    def format_stack_resource_detail(self, res):
-        return str(res)
-
-    def format_template(self, template):
-        return str(template)
-
-    def format_parameters(self, options):
-        '''
-        Reformat parameters into dict of format expected by the API
-        '''
-        parameters = {}
-        if options.parameters:
-            for count, p in enumerate(options.parameters.split(';'), 1):
-                (n, v) = p.split('=', 1)
-                parameters['Parameters.member.%d.ParameterKey' % count] = n
-                parameters['Parameters.member.%d.ParameterValue' % count] = v
-        return parameters
-
-
-HeatClient = V1Client
-
-
-def get_client(host, port=None, username=None,
-               password=None, tenant=None,
-               auth_url=None, auth_strategy=None,
-               auth_token=None, region=None,
-               is_silent_upload=False, insecure=False):
-    """
-    Returns a new client heat client object based on common kwargs.
-    If an option isn't specified falls back to common environment variable
-    defaults.
-    """
-
-    if auth_url:
-        force_strategy = 'keystone'
-    else:
-        force_strategy = None
-
-    creds = dict(username=username,
-                 password=password,
-                 tenant=tenant,
-                 auth_url=auth_url,
-                 strategy=force_strategy or auth_strategy,
-                 region=region)
-
-    if creds['strategy'] == 'keystone' and not creds['auth_url']:
-        msg = ("--auth_url option or OS_AUTH_URL environment variable "
-               "required when keystone authentication strategy is enabled\n")
-        raise exception.ClientConfigurationError(msg)
-
-    use_ssl = (creds['auth_url'] is not None and
-               creds['auth_url'].find('https') != -1)
-
-    client = HeatClient
-
-    return client(host=host,
-                  port=port,
-                  use_ssl=use_ssl,
-                  auth_tok=auth_token,
-                  creds=creds,
-                  insecure=insecure,
-                  service_type='cloudformation')
diff --git a/heat/cfn_client/utils.py b/heat/cfn_client/utils.py
deleted file mode 100644 (file)
index 58fb725..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    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.
-
-import functools
-from heat.common import exception
-from heat.openstack.common import log as logging
-
-LOG = logging.getLogger(__name__)
-
-SUCCESS = 0
-FAILURE = 1
-
-
-def catch_error(action):
-    """Decorator to provide sensible default error handling for CLI actions."""
-    def wrap(func):
-        @functools.wraps(func)
-        def wrapper(*arguments, **kwargs):
-            try:
-                ret = func(*arguments, **kwargs)
-                return SUCCESS if ret is None else ret
-            except exception.NotAuthorized:
-                LOG.error("Not authorized to make this request. Check " +
-                          "your credentials (OS_USERNAME, OS_PASSWORD, " +
-                          "OS_TENANT_NAME, OS_AUTH_URL and OS_AUTH_STRATEGY).")
-                return FAILURE
-            except exception.ClientConfigurationError:
-                raise
-            except exception.KeystoneError as e:
-                LOG.error("Keystone did not finish the authentication and "
-                          "returned the following message:\n\n%s" % e.message)
-                return FAILURE
-            except Exception as e:
-                options = arguments[0]
-                if options.debug:
-                    raise
-                LOG.error("Failed to %s. Got error:" % action)
-                pieces = unicode(e).split('\n')
-                for piece in pieces:
-                    LOG.error(piece)
-                return FAILURE
-
-        return wrapper
-    return wrap
diff --git a/heat/common/auth.py b/heat/common/auth.py
deleted file mode 100644 (file)
index 7ba3b9b..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    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.
-
-"""
-This auth module is intended to allow Openstack client-tools to select from a
-variety of authentication strategies, including NoAuth (the default), and
-Keystone (an identity management system).
-
-    > auth_plugin = AuthPlugin(creds)
-
-    > auth_plugin.authenticate()
-
-    > auth_plugin.auth_token
-    abcdefg
-
-    > auth_plugin.management_url
-    http://service_endpoint/
-"""
-import httplib2
-import json
-import urlparse
-
-from heat.common import exception
-
-from heat.openstack.common.gettextutils import _
-
-
-class BaseStrategy(object):
-    def __init__(self):
-        self.auth_token = None
-        # TODO(sirp): Should expose selecting public/internal/admin URL.
-        self.management_url = None
-
-    def authenticate(self):
-        raise NotImplementedError
-
-    @property
-    def is_authenticated(self):
-        raise NotImplementedError
-
-    @property
-    def strategy(self):
-        raise NotImplementedError
-
-
-class NoAuthStrategy(BaseStrategy):
-    def authenticate(self):
-        pass
-
-    @property
-    def is_authenticated(self):
-        return True
-
-    @property
-    def strategy(self):
-        return 'noauth'
-
-
-class KeystoneStrategy(BaseStrategy):
-    MAX_REDIRECTS = 10
-
-    def __init__(self, creds, service_type):
-        self.creds = creds
-        self.service_type = service_type
-        super(KeystoneStrategy, self).__init__()
-
-    def check_auth_params(self):
-        # Ensure that supplied credential parameters are as required
-        for required in ('username', 'password', 'auth_url',
-                         'strategy'):
-            if required not in self.creds:
-                raise exception.MissingCredentialError(required=required)
-        if self.creds['strategy'] != 'keystone':
-            raise exception.BadAuthStrategy(expected='keystone',
-                                            received=self.creds['strategy'])
-        # For v2.0 also check tenant is present
-        if self.creds['auth_url'].rstrip('/').endswith('v2.0'):
-            if 'tenant' not in self.creds:
-                raise exception.MissingCredentialError(required='tenant')
-
-    def authenticate(self):
-        """Authenticate with the Keystone service.
-
-        There are a few scenarios to consider here:
-
-        1. Which version of Keystone are we using? v1 which uses headers to
-           pass the credentials, or v2 which uses a JSON encoded request body?
-
-        2. Keystone may respond back with a redirection using a 305 status
-           code.
-
-        3. We may attempt a v1 auth when v2 is what's called for. In this
-           case, we rewrite the url to contain /v2.0/ and retry using the v2
-           protocol.
-        """
-        def _authenticate(auth_url):
-            # If OS_AUTH_URL is missing a trailing slash add one
-            if not auth_url.endswith('/'):
-                auth_url += '/'
-            token_url = urlparse.urljoin(auth_url, "tokens")
-            # 1. Check Keystone version
-            is_v2 = auth_url.rstrip('/').endswith('v2.0')
-            if is_v2:
-                self._v2_auth(token_url)
-            else:
-                self._v1_auth(token_url)
-
-        self.check_auth_params()
-        auth_url = self.creds['auth_url']
-        for x in range(self.MAX_REDIRECTS):
-            try:
-                _authenticate(auth_url)
-            except exception.AuthorizationRedirect as e:
-                # 2. Keystone may redirect us
-                auth_url = e.url
-            except exception.AuthorizationFailure:
-                # 3. In some configurations nova makes redirection to
-                # v2.0 keystone endpoint. Also, new location does not
-                # contain real endpoint, only hostname and port.
-                if 'v2.0' not in auth_url:
-                    auth_url = urlparse.urljoin(auth_url, 'v2.0/')
-            else:
-                # If we sucessfully auth'd, then memorize the correct auth_url
-                # for future use.
-                self.creds['auth_url'] = auth_url
-                break
-        else:
-            # Guard against a redirection loop
-            raise exception.MaxRedirectsExceeded(redirects=self.MAX_REDIRECTS)
-
-    def _v1_auth(self, token_url):
-        creds = self.creds
-
-        headers = {}
-        headers['X-Auth-User'] = creds['username']
-        headers['X-Auth-Key'] = creds['password']
-
-        tenant = creds.get('tenant')
-        if tenant:
-            headers['X-Auth-Tenant'] = tenant
-
-        resp, resp_body = self._do_request(token_url, 'GET', headers=headers)
-
-        def _management_url(self, resp):
-            for url_header in ('x-heat-management-url',
-                               'x-server-management-url',
-                               'x-heat'):
-                try:
-                    return resp[url_header]
-                except KeyError as e:
-                    not_found = e
-            raise not_found
-
-        if resp.status in (200, 204):
-            try:
-                self.management_url = _management_url(self, resp)
-                self.auth_token = resp['x-auth-token']
-            except KeyError:
-                raise exception.AuthorizationFailure()
-        elif resp.status == 305:
-            raise exception.AuthorizationRedirect(resp['location'])
-        elif resp.status == 400:
-            raise exception.AuthBadRequest(url=token_url)
-        elif resp.status == 401:
-            raise exception.NotAuthorized()
-        elif resp.status == 404:
-            raise exception.AuthUrlNotFound(url=token_url)
-        else:
-            status = resp.status
-            raise Exception(_('Unexpected response: %(status)s')
-                            % {'status': resp.status})
-
-    def _v2_auth(self, token_url):
-        def get_endpoint(service_catalog):
-            """
-            Select an endpoint from the service catalog
-
-            We search the full service catalog for services
-            matching both type and region. If the client
-            supplied no region then any endpoint for the service
-            is considered a match. There must be one -- and
-            only one -- successful match in the catalog,
-            otherwise we will raise an exception.
-            """
-            region = self.creds.get('region')
-
-            service_type_matches = lambda s: s.get('type') == self.service_type
-            region_matches = lambda e: region is None or e['region'] == region
-
-            endpoints = [ep for s in service_catalog if service_type_matches(s)
-                         for ep in s['endpoints'] if region_matches(ep)]
-
-            if len(endpoints) > 1:
-                raise exception.RegionAmbiguity(region=region)
-            elif not endpoints:
-                raise exception.NoServiceEndpoint()
-            else:
-                # FIXME(sirp): for now just use the public url.
-                return endpoints[0]['publicURL']
-
-        creds = self.creds
-
-        creds = {
-            "auth": {
-                "tenantName": creds['tenant'],
-                "passwordCredentials": {
-                    "username": creds['username'],
-                    "password": creds['password']}}}
-
-        headers = {}
-        headers['Content-Type'] = 'application/json'
-        req_body = json.dumps(creds)
-
-        resp, resp_body = self._do_request(
-            token_url, 'POST', headers=headers, body=req_body)
-
-        if resp.status == 200:
-            resp_auth = json.loads(resp_body)['access']
-            self.management_url = get_endpoint(resp_auth['serviceCatalog'])
-            self.auth_token = resp_auth['token']['id']
-        elif resp.status == 305:
-            raise exception.RedirectException(resp['location'])
-        elif resp.status == 400:
-            raise exception.AuthBadRequest(url=token_url)
-        elif resp.status == 401:
-            raise exception.NotAuthorized()
-        elif resp.status == 404:
-            raise exception.AuthUrlNotFound(url=token_url)
-        else:
-            try:
-                body = json.loads(resp_body)
-                msg = body['error']['message']
-            except (ValueError, KeyError):
-                msg = resp_body
-            raise exception.KeystoneError(resp.status, msg)
-
-    @property
-    def is_authenticated(self):
-        return self.auth_token is not None
-
-    @property
-    def strategy(self):
-        return 'keystone'
-
-    @staticmethod
-    def _do_request(url, method, headers=None, body=None):
-        headers = headers or {}
-        conn = httplib2.Http()
-        conn.force_exception_to_status_code = True
-        headers['User-Agent'] = 'heat-client'
-        resp, resp_body = conn.request(url, method, headers=headers, body=body)
-        return resp, resp_body
-
-
-def get_plugin_from_strategy(strategy, creds=None, service_type=None):
-    if strategy == 'noauth':
-        return NoAuthStrategy()
-    elif strategy == 'keystone':
-        return KeystoneStrategy(creds, service_type)
-    else:
-        raise Exception(_("Unknown auth strategy '%s'") % strategy)
diff --git a/heat/common/client.py b/heat/common/client.py
deleted file mode 100644 (file)
index b16b8c6..0000000
+++ /dev/null
@@ -1,548 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#
-#    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.
-
-# HTTPSClientAuthConnection code comes courtesy of ActiveState website:
-# http://code.activestate.com/recipes/
-#   577548-https-httplib-client-connection-with-certificate-v/
-
-import collections
-import functools
-import httplib
-import os
-import urllib
-import urlparse
-
-try:
-    from eventlet.green import socket
-    from eventlet.green import ssl
-except ImportError:
-    import socket
-    import ssl
-
-from heat.common import auth
-from heat.common import exception
-from heat.common import utils
-
-from heat.openstack.common.gettextutils import _
-
-
-# common chunk size for get and put
-CHUNKSIZE = 65536
-
-
-def handle_unauthorized(func):
-    """
-    Wrap a function to re-authenticate and retry.
-    """
-    @functools.wraps(func)
-    def wrapped(self, *args, **kwargs):
-        try:
-            return func(self, *args, **kwargs)
-        except exception.NotAuthorized:
-            self._authenticate(force_reauth=True)
-            return func(self, *args, **kwargs)
-    return wrapped
-
-
-def handle_redirects(func):
-    """
-    Wrap the _do_request function to handle HTTP redirects.
-    """
-    MAX_REDIRECTS = 5
-
-    @functools.wraps(func)
-    def wrapped(self, method, url, body, headers):
-        for _ in xrange(MAX_REDIRECTS):
-            try:
-                return func(self, method, url, body, headers)
-            except exception.RedirectException as redirect:
-                if redirect.url is None:
-                    raise exception.InvalidRedirect()
-                url = redirect.url
-        raise exception.MaxRedirectsExceeded(redirects=MAX_REDIRECTS)
-    return wrapped
-
-
-class ImageBodyIterator(object):
-
-    """
-    A class that acts as an iterator over an image file's
-    chunks of data.  This is returned as part of the result
-    tuple from `heat.cfn_client.client.Client.get_image`
-    """
-
-    def __init__(self, source):
-        """
-        Constructs the object from a readable image source
-        (such as an HTTPResponse or file-like object)
-        """
-        self.source = source
-
-    def __iter__(self):
-        """
-        Exposes an iterator over the chunks of data in the
-        image file.
-        """
-        while True:
-            chunk = self.source.read(CHUNKSIZE)
-            if chunk:
-                yield chunk
-            else:
-                break
-
-
-class HTTPSClientAuthConnection(httplib.HTTPSConnection):
-    """
-    Class to make a HTTPS connection, with support for
-    full client-based SSL Authentication
-
-    :see http://code.activestate.com/recipes/
-            577548-https-httplib-client-connection-with-certificate-v/
-    """
-
-    def __init__(self, host, port, key_file, cert_file,
-                 ca_file, timeout=None, insecure=False):
-        httplib.HTTPSConnection.__init__(self, host, port, key_file=key_file,
-                                         cert_file=cert_file)
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.ca_file = ca_file
-        self.timeout = timeout
-        self.insecure = insecure
-
-    def connect(self):
-        """
-        Connect to a host on a given (SSL) port.
-        If ca_file is pointing somewhere, use it to check Server Certificate.
-
-        Redefined/copied and extended from httplib.py:1105 (Python 2.6.x).
-        This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter to
-        ssl.wrap_socket(), which forces SSL to check server certificate against
-        our client certificate.
-        """
-        sock = socket.create_connection((self.host, self.port), self.timeout)
-        if self._tunnel_host:
-            self.sock = sock
-            self._tunnel()
-        # Check CA file unless 'insecure' is specificed
-        if self.insecure is True:
-            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
-                                        cert_reqs=ssl.CERT_NONE)
-        else:
-            self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
-                                        ca_certs=self.ca_file,
-                                        cert_reqs=ssl.CERT_REQUIRED)
-
-
-class BaseClient(object):
-
-    """A base client class."""
-
-    DEFAULT_PORT = 80
-    DEFAULT_DOC_ROOT = None
-    # Standard CA file locations for Debian/Ubuntu, RedHat/Fedora,
-    # Suse, FreeBSD/OpenBSD
-    DEFAULT_CA_FILE_PATH = '/etc/ssl/certs/ca-certificates.crt:'\
-        '/etc/pki/tls/certs/ca-bundle.crt:'\
-        '/etc/ssl/ca-bundle.pem:'\
-        '/etc/ssl/cert.pem'
-
-    OK_RESPONSE_CODES = (
-        httplib.OK,
-        httplib.CREATED,
-        httplib.ACCEPTED,
-        httplib.NO_CONTENT,
-    )
-
-    REDIRECT_RESPONSE_CODES = (
-        httplib.MOVED_PERMANENTLY,
-        httplib.FOUND,
-        httplib.SEE_OTHER,
-        httplib.USE_PROXY,
-        httplib.TEMPORARY_REDIRECT,
-    )
-
-    def __init__(self, host=None, port=None, use_ssl=False, auth_tok=None,
-                 creds=None, doc_root=None, key_file=None,
-                 cert_file=None, ca_file=None, insecure=False,
-                 configure_via_auth=True, service_type=None):
-        """
-        Creates a new client to some service.
-
-        :param host: The host where service resides
-        :param port: The port where service resides
-        :param use_ssl: Should we use HTTPS?
-        :param auth_tok: The auth token to pass to the server
-        :param creds: The credentials to pass to the auth plugin
-        :param doc_root: Prefix for all URLs we request from host
-        :param key_file: Optional PEM-formatted file that contains the private
-                         key.
-                         If use_ssl is True, and this param is None (the
-                         default), then an environ variable
-                         HEAT_CLIENT_KEY_FILE is looked for. If no such
-                         environ variable is found, ClientConnectionError
-                         will be raised.
-        :param cert_file: Optional PEM-formatted certificate chain file.
-                          If use_ssl is True, and this param is None (the
-                          default), then an environ variable
-                          HEAT_CLIENT_CERT_FILE is looked for. If no such
-                          environ variable is found, ClientConnectionError
-                          will be raised.
-        :param ca_file: Optional CA cert file to use in SSL connections
-                        If use_ssl is True, and this param is None (the
-                        default), then an environ variable
-                        HEAT_CLIENT_CA_FILE is looked for.
-        :param insecure: Optional. If set then the server's certificate
-                         will not be verified.
-        """
-        self.host = host
-        self.port = port or self.DEFAULT_PORT
-        self.use_ssl = use_ssl
-        self.auth_tok = auth_tok
-        self.creds = creds or {}
-        self.connection = None
-        self.configure_via_auth = configure_via_auth
-        self.service_type = service_type
-        # doc_root can be a nullstring, which is valid, and why we
-        # cannot simply do doc_root or self.DEFAULT_DOC_ROOT below.
-        self.doc_root = (doc_root if doc_root is not None
-                         else self.DEFAULT_DOC_ROOT)
-        self.auth_plugin = self.make_auth_plugin(self.creds)
-
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.ca_file = ca_file
-        self.insecure = insecure
-        self.connect_kwargs = self.get_connect_kwargs()
-
-    def get_connect_kwargs(self):
-        connect_kwargs = {}
-        if self.use_ssl:
-            if self.key_file is None:
-                self.key_file = os.environ.get('HEAT_CLIENT_KEY_FILE')
-            if self.cert_file is None:
-                self.cert_file = os.environ.get('HEAT_CLIENT_CERT_FILE')
-            if self.ca_file is None:
-                self.ca_file = os.environ.get('HEAT_CLIENT_CA_FILE')
-
-            # Check that key_file/cert_file are either both set or both unset
-            if self.cert_file is not None and self.key_file is None:
-                msg = _("You have selected to use SSL in connecting, "
-                        "and you have supplied a cert, "
-                        "however you have failed to supply either a "
-                        "key_file parameter or set the "
-                        "HEAT_CLIENT_KEY_FILE environ variable")
-                raise exception.ClientConnectionError(msg)
-
-            if self.key_file is not None and self.cert_file is None:
-                msg = _("You have selected to use SSL in connecting, "
-                        "and you have supplied a key, "
-                        "however you have failed to supply either a "
-                        "cert_file parameter or set the "
-                        "HEAT_CLIENT_CERT_FILE environ variable")
-                raise exception.ClientConnectionError(msg)
-
-            if (self.key_file is not None and
-                    not os.path.exists(self.key_file)):
-                msg = _("The key file you specified %s does not "
-                        "exist") % self.key_file
-                raise exception.ClientConnectionError(msg)
-            connect_kwargs['key_file'] = self.key_file
-
-            if (self.cert_file is not None and
-                    not os.path.exists(self.cert_file)):
-                msg = _("The cert file you specified %s does not "
-                        "exist") % self.cert_file
-                raise exception.ClientConnectionError(msg)
-            connect_kwargs['cert_file'] = self.cert_file
-
-            if (self.ca_file is not None and
-                    not os.path.exists(self.ca_file)):
-                msg = _("The CA file you specified %s does not "
-                        "exist") % self.ca_file
-                raise exception.ClientConnectionError(msg)
-
-            if self.ca_file is None:
-                for ca in self.DEFAULT_CA_FILE_PATH.split(":"):
-                    if os.path.exists(ca):
-                        self.ca_file = ca
-                        break
-
-            connect_kwargs['ca_file'] = self.ca_file
-            connect_kwargs['insecure'] = self.insecure
-
-        return connect_kwargs
-
-    def set_auth_token(self, auth_tok):
-        """
-        Updates the authentication token for this client connection.
-        """
-        # FIXME(sirp): Nova image/heat.py currently calls this. Since this
-        # method isn't really doing anything useful[1], we should go ahead and
-        # rip it out, first in Nova, then here. Steps:
-        #
-        #       1. Change auth_tok in heat to auth_token
-        #       2. Change image/heat.py in Nova to use client.auth_token
-        #       3. Remove this method
-        #
-        # [1] http://mail.python.org/pipermail/tutor/2003-October/025932.html
-        self.auth_tok = auth_tok
-
-    def configure_from_url(self, url):
-        """
-        Setups the connection based on the given url.
-
-        The form is:
-
-            <http|https>://<host>:port/doc_root
-        """
-        parsed = urlparse.urlparse(url)
-        self.use_ssl = parsed.scheme == 'https'
-        if self.host is None:
-            self.host = parsed.hostname
-        self.port = parsed.port or 80
-        self.doc_root = parsed.path
-
-        # ensure connection kwargs are re-evaluated after the service catalog
-        # publicURL is parsed for potential SSL usage
-        self.connect_kwargs = self.get_connect_kwargs()
-
-    def make_auth_plugin(self, creds):
-        """
-        Returns an instantiated authentication plugin.
-        """
-        strategy = creds.get('strategy', 'noauth')
-        plugin = auth.get_plugin_from_strategy(strategy,
-                                               creds, self.service_type)
-        return plugin
-
-    def get_connection_type(self):
-        """
-        Returns the proper connection type
-        """
-        if self.use_ssl:
-            return HTTPSClientAuthConnection
-        else:
-            return httplib.HTTPConnection
-
-    def _authenticate(self, force_reauth=False):
-        """
-        Use the authentication plugin to authenticate and set the auth token.
-
-        :param force_reauth: For re-authentication to bypass cache.
-        """
-        auth_plugin = self.auth_plugin
-
-        if not auth_plugin.is_authenticated or force_reauth:
-            auth_plugin.authenticate()
-
-        self.auth_tok = auth_plugin.auth_token
-
-        management_url = auth_plugin.management_url
-        if management_url and self.configure_via_auth:
-            self.configure_from_url(management_url)
-
-    @handle_unauthorized
-    def do_request(self, method, action, body=None, headers=None,
-                   params=None):
-        """
-        Make a request, returning an HTTP response object.
-
-        :param method: HTTP verb (GET, POST, PUT, etc.)
-        :param action: Requested path to append to self.doc_root
-        :param body: Data to send in the body of the request
-        :param headers: Headers to send with the request
-        :param params: Key/value pairs to use in query string
-        :returns: HTTP response object
-        """
-        if not self.auth_tok:
-            self._authenticate()
-
-        url = self._construct_url(action, params)
-        return self._do_request(method=method, url=url, body=body,
-                                headers=headers)
-
-    def _construct_url(self, action, params=None):
-        """
-        Create a URL object we can use to pass to _do_request().
-        """
-        path = '/'.join([self.doc_root or '', action.lstrip('/')])
-        scheme = "https" if self.use_ssl else "http"
-        netloc = "%s:%d" % (self.host, self.port)
-
-        if isinstance(params, dict):
-            for (key, value) in params.items():
-                if value is None:
-                    del params[key]
-            query = urllib.urlencode(params)
-        else:
-            query = None
-
-        return urlparse.ParseResult(scheme, netloc, path, '', query, '')
-
-    @handle_redirects
-    def _do_request(self, method, url, body, headers):
-        """
-        Connects to the server and issues a request.  Handles converting
-        any returned HTTP error status codes to OpenStack/heat exceptions
-        and closing the server connection. Returns the result data, or
-        raises an appropriate exception.
-
-        :param method: HTTP method ("GET", "POST", "PUT", etc...)
-        :param url: urlparse.ParsedResult object with URL information
-        :param body: data to send (as string, filelike or iterable),
-                     or None (default)
-        :param headers: mapping of key/value pairs to add as headers
-
-        :note
-
-        If the body param has a read attribute, and method is either
-        POST or PUT, this method will automatically conduct a chunked-transfer
-        encoding and use the body as a file object or iterable, transferring
-        chunks of data using the connection's send() method. This allows large
-        objects to be transferred efficiently without buffering the entire
-        body in memory.
-        """
-        if url.query:
-            path = url.path + "?" + url.query
-        else:
-            path = url.path
-
-        try:
-            connection_type = self.get_connection_type()
-            headers = headers or {}
-
-            if 'x-auth-token' not in headers and self.auth_tok:
-                headers['x-auth-token'] = self.auth_tok
-
-            c = connection_type(url.hostname, url.port, **self.connect_kwargs)
-
-            def _pushing(method):
-                return method.lower() in ('post', 'put')
-
-            def _simple(body):
-                return body is None or isinstance(body, basestring)
-
-            def _filelike(body):
-                return hasattr(body, 'read')
-
-            def _sendbody(connection, iter):
-                connection.endheaders()
-                for sent in iter:
-                    # iterator has done the heavy lifting
-                    pass
-
-            def _chunkbody(connection, iter):
-                connection.putheader('Transfer-Encoding', 'chunked')
-                connection.endheaders()
-                for chunk in iter:
-                    connection.send('%x\r\n%s\r\n' % (len(chunk), chunk))
-                connection.send('0\r\n\r\n')
-
-            # Do a simple request or a chunked request, depending
-            # on whether the body param is file-like or iterable and
-            # the method is PUT or POST
-            #
-            if not _pushing(method) or _simple(body):
-                # Simple request...
-                c.request(method, path, body, headers)
-            elif _filelike(body) or self._iterable(body):
-                c.putrequest(method, path)
-
-                for header, value in headers.items():
-                    c.putheader(header, value)
-
-                iter = self.image_iterator(c, headers, body)
-
-                _chunkbody(c, iter)
-            else:
-                raise TypeError('Unsupported image type: %s' % body.__class__)
-
-            res = c.getresponse()
-
-            def _retry(res):
-                return res.getheader('Retry-After')
-
-            status_code = self.get_status_code(res)
-            if status_code in self.OK_RESPONSE_CODES:
-                return res
-            elif status_code in self.REDIRECT_RESPONSE_CODES:
-                raise exception.RedirectException(res.getheader('Location'))
-            elif status_code == httplib.UNAUTHORIZED:
-                raise exception.NotAuthorized()
-            elif status_code == httplib.FORBIDDEN:
-                raise exception.NotAuthorized()
-            elif status_code == httplib.NOT_FOUND:
-                raise exception.NotFound(res.read())
-            elif status_code == httplib.CONFLICT:
-                raise exception.Duplicate(res.read())
-            elif status_code == httplib.BAD_REQUEST:
-                raise exception.Invalid(reason=res.read())
-            elif status_code == httplib.MULTIPLE_CHOICES:
-                raise exception.MultipleChoices(body=res.read())
-            elif status_code == httplib.REQUEST_ENTITY_TOO_LARGE:
-                raise exception.LimitExceeded(retry=_retry(res),
-                                              body=res.read())
-            elif status_code == httplib.INTERNAL_SERVER_ERROR:
-                raise Exception("Internal Server error: %s" % res.read())
-            elif status_code == httplib.SERVICE_UNAVAILABLE:
-                raise exception.ServiceUnavailable(retry=_retry(res))
-            elif status_code == httplib.REQUEST_URI_TOO_LONG:
-                raise exception.RequestUriTooLong(body=res.read())
-            else:
-                raise Exception("Unknown error occurred! %s" % res.read())
-
-        except (socket.error, IOError) as e:
-            raise exception.ClientConnectionError(e)
-
-    def _iterable(self, body):
-        return isinstance(body, collections.Iterable)
-
-    def image_iterator(self, connection, headers, body):
-        if self._iterable(body):
-            return utils.chunkreadable(body)
-        else:
-            return ImageBodyIterator(body)
-
-    def get_status_code(self, response):
-        """
-        Returns the integer status code from the response, which
-        can be either a Webob.Response (used in testing) or httplib.Response
-        """
-        if hasattr(response, 'status_int'):
-            return response.status_int
-        else:
-            return response.status
-
-    def _extract_params(self, actual_params, allowed_params):
-        """
-        Extract a subset of keys from a dictionary. The filters key
-        will also be extracted, and each of its values will be returned
-        as an individual param.
-
-        :param actual_params: dict of keys to filter
-        :param allowed_params: list of keys that 'actual_params' will be
-                               reduced to
-        :retval subset of 'params' dict
-        """
-        result = {}
-
-        for param in actual_params:
-            if param in allowed_params:
-                result[param] = actual_params[param]
-            elif 'Parameters.member.' in param:
-                result[param] = actual_params[param]
-
-        return result
diff --git a/heat/common/utils.py b/heat/common/utils.py
deleted file mode 100644 (file)
index b651211..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-#    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.
-
-"""
-System-level utilities and helper functions.
-"""
-
-from heat.openstack.common import log as logging
-
-
-LOG = logging.getLogger(__name__)
-
-
-def chunkreadable(iter, chunk_size=65536):
-    """
-    Wrap a readable iterator with a reader yielding chunks of
-    a preferred size, otherwise leave iterator unchanged.
-
-    :param iter: an iter which may also be readable
-    :param chunk_size: maximum size of chunk
-    """
-    return chunkiter(iter, chunk_size) if hasattr(iter, 'read') else iter
-
-
-def chunkiter(fp, chunk_size=65536):
-    """
-    Return an iterator to a file-like obj which yields fixed size chunks
-
-    :param fp: a file-like object
-    :param chunk_size: maximum size of chunk
-    """
-    while True:
-        chunk = fp.read(chunk_size)
-        if chunk:
-            yield chunk
-        else:
-            break
diff --git a/heat/tests/test_cli.py b/heat/tests/test_cli.py
deleted file mode 100644 (file)
index 464ce6b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-#    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.
-
-
-import testtools
-import heat
-import os
-import subprocess
-
-basepath = os.path.join(heat.__path__[0], os.path.pardir)
-
-
-class CliTest(testtools.TestCase):
-
-    def test_heat_cfn(self):
-            self.bin_run('heat-cfn')
-
-    def test_heat_boto(self):
-            self.bin_run('heat-boto')
-
-    def test_heat_watch(self):
-            self.bin_run('heat-watch')
-
-    def bin_run(self, bin):
-            fullpath = basepath + '/bin/' + bin
-
-            proc = subprocess.Popen(fullpath,
-                                    stdout=subprocess.PIPE,
-                                    stderr=subprocess.PIPE)
-            stdout, stderr = proc.communicate()
-
-            if proc.returncode:
-                print('Error executing %s:\n %s %s ' % (bin, stdout, stderr))
-                raise subprocess.CalledProcessError(proc.returncode, bin)
index d301693d33962393a76ae46254b48f6289fb5b90..c9f0f9cd5db49defc5bce421d2aa5f0218ae9f0b 100644 (file)
@@ -1,6 +1,5 @@
 pbr>=0.5.21,<1.0
 pycrypto>=2.6
-boto>=2.4.0
 eventlet>=0.13.0
 greenlet>=0.3.2
 httplib2
index b58f60dfe7335e10b347d0431b07fe4f12faf4d3..22949f69b58c4697cb29961e4a22586d02ca2460 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -26,13 +26,10 @@ scripts =
     bin/heat-api
     bin/heat-api-cfn
     bin/heat-api-cloudwatch
-    bin/heat-boto
-    bin/heat-cfn
     bin/heat-db-setup
     bin/heat-engine
     bin/heat-keystone-setup
     bin/heat-manage
-    bin/heat-watch
 
 [global]
 setup-hooks =
index 26a54661f68fb69b8bfc1d566daf6d103ebf4903..bf44515f42f135ff0a80595a8ecb2d87520ef307 100755 (executable)
@@ -62,7 +62,6 @@ if user_wants 'Delete Heat binaries?'; then
     sudo rm -f $BIN_PATH/heat-api
     sudo rm -f $BIN_PATH/heat-api-cfn
     sudo rm -f $BIN_PATH/heat-engine
-    sudo rm -f $BIN_PATH/heat-cfn
 
     echo 1>&2
 fi