152 lines
5.5 KiB

# Copyright 2012-2013 OpenStack Foundation
# Copyright 2015 Dean Troyer
# 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
# 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.
"""Command-line interface to the OpenStack APIs"""
import sys
import warnings
from osc_lib.api import auth
from osc_lib.command import commandmanager
from osc_lib import shell
import openstackclient
from openstackclient.common import clientmanager
DEFAULT_DOMAIN = 'default'
class OpenStackShell(shell.OpenStackShell):
def __init__(self):
self.api_version = {}
# Assume TLS host certificate verification is enabled
self.verify = True
# ignore warnings from openstacksdk since our users can't do anything
# about them
warnings.filterwarnings('ignore', module='openstack')
def build_option_parser(self, description, version):
parser = super().build_option_parser(description, version)
parser = clientmanager.build_plugin_option_parser(parser)
parser = auth.build_auth_plugins_option_parser(parser)
return parser
def _final_defaults(self):
# Set the default plugin to admin_token if endpoint and token are given
if self.options.endpoint and self.options.token:
# Use token authentication
self._auth_type = 'admin_token'
self._auth_type = 'password'
def _load_plugins(self):
"""Load plugins via stevedore
osc-lib has no opinion on what plugins should be loaded
# Loop through extensions to get API versions
for mod in clientmanager.PLUGIN_MODULES:
default_version = getattr(mod, 'DEFAULT_API_VERSION', None)
# Only replace the first instance of "os", some service names will
# have "os" in their name, like: "antiddos"
option = mod.API_VERSION_OPTION.replace('os_', '', 1)
version_opt = str(, default_version))
if version_opt:
api = mod.API_NAME
self.api_version[api] = version_opt
# Add a plugin interface to let the module validate the version
# requested by the user
skip_old_check = False
mod_check_api_version = getattr(mod, 'check_api_version', None)
if mod_check_api_version:
# this throws an exception if invalid
skip_old_check = mod_check_api_version(version_opt)
mod_versions = getattr(mod, 'API_VERSIONS', None)
if not skip_old_check and mod_versions:
if version_opt not in mod_versions:
sorted_versions = sorted(
key=lambda s: list(map(int, s.split('.'))),
"%s version %s is not in supported versions: %s"
% (api, version_opt, ', '.join(sorted_versions))
# Command groups deal only with major versions
version = '.v' + version_opt.replace('.', '_').split('_')[0]
cmd_group = 'openstack.' + api.replace('-', '_') + version
'%(name)s API version %(version)s, cmd group %(group)s',
{'name': api, 'version': version_opt, 'group': cmd_group},
def _load_commands(self):
"""Load commands via cliff/stevedore
osc-lib has no opinion on what commands should be loaded
# Commands that span multiple APIs
# This is the naive extension implementation referred to in
# blueprint 'client-extensions'
# Extension modules can register their commands in an
# 'openstack.extension' entry point group:
# entry_points={
# 'openstack.extension': [
# 'list_repo=qaz.github.repo:ListRepo',
# 'show_repo=qaz.github.repo:ShowRepo',
# ],
# }
def initialize_app(self, argv):
# Re-create the client_manager with our subclass
self.client_manager = clientmanager.ClientManager(,
def main(argv=None):
if argv is None:
argv = sys.argv[1:]
return OpenStackShell().run(argv)
if __name__ == "__main__":