You can use supernova with many OpenStack clients and avoid the pain of
    managing multiple sets of environment variables.  Getting started is easy
    and there's some documentation that can help:

      http://supernova.readthedocs.org/

    The first step is to get your environment variables packed into a
    configuration file, usually in ~/.supernova.  The docs (linked above) have
    some good examples that you can fill in via copy/paste.

    Once you have a configuration ready to go, replace 'prod' below with one
    of your configured environments and try some of these commands:

      supernova prod list                 (Lists instances via novaclient)
      supernova prod image-list           (Lists images via novaclient)
      supernova prod boot ...             (Boots an instance via novaclient)

    Have questions, bugs, or comments?  Head on over to Github and open an
    issue or submit a pull request!

      https://github.com/major/supernova

def run_supernova(ctx, executable, debug, quiet, environment, command, conf,
                  echo, dashboard):
    """
    You can use supernova with many OpenStack clients and avoid the pain of
    managing multiple sets of environment variables.  Getting started is easy
    and there's some documentation that can help:

      http://supernova.readthedocs.org/

    The first step is to get your environment variables packed into a
    configuration file, usually in ~/.supernova.  The docs (linked above) have
    some good examples that you can fill in via copy/paste.

    Once you have a configuration ready to go, replace 'prod' below with one
    of your configured environments and try some of these commands:

      supernova prod list                 (Lists instances via novaclient)
      supernova prod image-list           (Lists images via novaclient)
      supernova prod boot ...             (Boots an instance via novaclient)

    Have questions, bugs, or comments?  Head on over to Github and open an
    issue or submit a pull request!

      https://github.com/major/supernova
    """
    # Retrieve our credentials from the configuration file
    try:
        nova_creds = config.run_config(config_file_override=conf)
    except Exception as e:
        msg = ("\n  There's an error in your configuration file:\n\n"
               "    {0}\n").format(e)
        click.echo(msg)
        ctx.exit(1)

    # Warn the user if there are potentially conflicting environment variables
    # already set in the user's environment.
    utils.check_environment_presets()

    # Is our environment argument a single environment or a supernova group?
    if utils.is_valid_group(environment, nova_creds):
        envs = utils.get_envs_in_group(environment, nova_creds)
    elif ',' in environment:
        envs = []

        for env in environment.split(','):
            if utils.is_valid_group(env, nova_creds):
                envs.extend(utils.get_envs_in_group(env, nova_creds))
            else:
                envs.append(env)
    elif environment.startswith('/') and environment.endswith('/'):
        envs = [nova_env for nova_env in nova_creds.keys()
                if re.search(environment[1:-1], nova_env)]
    else:
        envs = [environment]

    # These are arguments for supernova and not the executable that supernova
    # will eventually call.
    supernova_args = {
        'debug': debug,
        'executable': executable,
        'quiet': quiet,
        'echo': echo,
        'dashboard': dashboard,
    }

    # If the user specified a single environment, we need to verify that the
    # environment actually exists in their configuration file.
    if len(envs) == 1 and not utils.is_valid_environment(envs[0], nova_creds):
        msg = ("\nCouldn't find an environment called '{0}' in your "
               "configuration file.\nTry supernova --list to see all "
               "configured environments.\n".format(envs[0]))
        click.echo(msg)
        ctx.exit(1)

    if supernova_args['echo']:
        if len(envs) > 1:
            msg = ("\nCan't echo a group of environments.\nSpecify a single "
                   "environment when using --echo.")
            click.echo(msg)
            ctx.exit(1)
        env = credentials.prep_shell_environment(envs[0], nova_creds)
        for k in env:
            click.echo('{0}={1}'.format(k, env[k]))
        ctx.exit(0)

    if supernova_args['dashboard']:
        if len(envs) > 1:
            msg = ("\nCan't open dashboard for a group of environments.\n"
                   "Specify a single environment when using --dashboard.")
            click.echo(msg)
            ctx.exit(1)
        url = nova_creds[envs[0]].get('SUPERNOVA_DASHBOARD_URL')
        if url is None:
            msg = ("\nNo SUPERNOVA_DASHBOARD_URL specified "
                   "for environment: %s" % envs[0])
            click.echo(msg)
            ctx.exit(1)
        webbrowser.open(url)
        ctx.exit(0)

    if len(command) == 0:
        msg = ("\nMissing arguments to pass to executable  Run supernova "
               "--help for examples.\n".format(envs[0]))
        click.echo(msg)
        ctx.exit(1)

    nova_args = list(command)

    # Loop through the single environment (if the user specified one) or all
    # of the environments in a supernova group (if the user specified a group).
    for env in envs:
        supernova_args['nova_env'] = env
        returncode = supernova.run_command(nova_creds, nova_args,
                                           supernova_args)

    # NOTE(major): The return code here is the one that comes back from the
    # OS_EXECUTABLE that supernova runs (by default, 'nova').  When using
    # supernova groups, the return code is the one returned by the executable
    # for the last environment in the group.
    #
    # It's not ideal, but it's all I can think of for now. ;)
    sys.exit(returncode)