Add entry points for kb client
Created initial directory structure for KB commands to work. Modify setup.cfg to add entry point. Refactored shell.py to display help, bash-completion and exceptions for invalid credentials. Add testcases for the same. Change-Id: I8d31aef2722c73572074754f7a608b720ce2f678
This commit is contained in:
parent
f6e549f9be
commit
fda1462d75
5
kingbirdclient/commands/README.rst
Normal file
5
kingbirdclient/commands/README.rst
Normal file
@ -0,0 +1,5 @@
|
||||
===============================
|
||||
Commands
|
||||
================================
|
||||
|
||||
This module helps in mapping kingbird commands to APIs.
|
0
kingbirdclient/commands/__init__.py
Normal file
0
kingbirdclient/commands/__init__.py
Normal file
@ -38,3 +38,12 @@ class IllegalArgumentException(KingbirdClientException):
|
||||
def __init__(self, message=None):
|
||||
if message:
|
||||
self.message = message
|
||||
|
||||
|
||||
class CommandError(KingbirdClientException):
|
||||
message = "CommandErrorException occurred"
|
||||
code = "COMMAND_ERROR_EXCEPTION"
|
||||
|
||||
def __init__(self, message=None):
|
||||
if message:
|
||||
self.message = message
|
||||
|
@ -21,6 +21,7 @@ import sys
|
||||
|
||||
from kingbirdclient import __version__ as kingbird_version
|
||||
from kingbirdclient.api import client
|
||||
from kingbirdclient import exceptions
|
||||
from kingbirdclient.openstack.common import cliutils as c
|
||||
|
||||
from cliff import app
|
||||
@ -289,19 +290,6 @@ class KingbirdShell(app.App):
|
||||
'(Env: KINGBIRDCLIENT_INSECURE)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--profile',
|
||||
dest='profile',
|
||||
metavar='HMAC_KEY',
|
||||
help='HMAC key to use for encrypting context data for performance '
|
||||
'profiling of operation. This key should be one of the '
|
||||
'values configured for the osprofiler middleware in mistral, '
|
||||
'it is specified in the profiler section of the mistral '
|
||||
'configuration (i.e. /etc/kingbird/kingbird.conf). '
|
||||
'Without the key, profiling will not be triggered even if '
|
||||
'osprofiler is enabled on the server side.'
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def initialize_app(self, argv):
|
||||
@ -311,19 +299,33 @@ class KingbirdShell(app.App):
|
||||
|
||||
self._set_shell_commands(self._get_commands(ver))
|
||||
|
||||
do_help = ('help' in argv) or ('-h' in argv) or not argv
|
||||
|
||||
# Set default for auth_url if not supplied. The default is not
|
||||
# set at the parser to support use cases where auth is not enabled.
|
||||
# An example use case would be a developer's environment.
|
||||
if not self.options.auth_url:
|
||||
if self.options.password or self.options.token:
|
||||
self.options.auth_url = 'http://localhost:35357/v3'
|
||||
do_help = ['help', '-h', 'bash-completion']
|
||||
|
||||
# bash-completion should not require authentication.
|
||||
if do_help or ('bash-completion' in argv):
|
||||
skip_auth = ''.join(argv) in do_help
|
||||
|
||||
if skip_auth:
|
||||
self.options.auth_url = None
|
||||
|
||||
if self.options.auth_url and not self.options.token \
|
||||
and not skip_auth:
|
||||
if not self.options.tenant_name:
|
||||
raise exceptions.CommandError(
|
||||
("You must provide a tenant_name "
|
||||
"via --os-tenantname env[OS_TENANT_NAME]")
|
||||
)
|
||||
if not self.options.username:
|
||||
raise exceptions.CommandError(
|
||||
("You must provide a username "
|
||||
"via --os-username env[OS_USERNAME]")
|
||||
)
|
||||
|
||||
if not self.options.password:
|
||||
raise exceptions.CommandError(
|
||||
("You must provide a password "
|
||||
"via --os-password env[OS_PASSWORD]")
|
||||
)
|
||||
|
||||
self.client = client.client(
|
||||
kingbird_url=self.options.kingbird_url,
|
||||
username=self.options.username,
|
||||
@ -335,10 +337,17 @@ class KingbirdShell(app.App):
|
||||
service_type=self.options.service_type,
|
||||
auth_token=self.options.token,
|
||||
cacert=self.options.cacert,
|
||||
insecure=self.options.insecure,
|
||||
profile=self.options.profile
|
||||
insecure=self.options.insecure
|
||||
)
|
||||
|
||||
if not self.options.auth_url and not skip_auth:
|
||||
raise exceptions.CommandError(
|
||||
("You must provide an auth url via either"
|
||||
"--os-auth-url or env[OS_AUTH_URL] or "
|
||||
"specify an auth_system which defines a"
|
||||
" default url with --os-auth-system or env[OS_AUTH_SYSTEM]")
|
||||
)
|
||||
|
||||
def _set_shell_commands(self, cmds_dict):
|
||||
for k, v in cmds_dict.items():
|
||||
self.command_manager.add_command(k, v)
|
||||
|
38
kingbirdclient/tests/test_help_and_bash_completion.py
Normal file
38
kingbirdclient/tests/test_help_and_bash_completion.py
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright 2016 Ericsson AB.
|
||||
#
|
||||
# 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 re
|
||||
|
||||
from testtools import matchers
|
||||
|
||||
from kingbirdclient.tests import base_shell_test as base
|
||||
|
||||
|
||||
class TestCLIBashCompletionV1(base.BaseShellTests):
|
||||
def test_bash_completion(self):
|
||||
bash_completion, stderr = self.shell('bash-completion')
|
||||
self.assertIn('bash-completion', bash_completion)
|
||||
self.assertFalse(stderr)
|
||||
|
||||
|
||||
class TestCLIHelp(base.BaseShellTests):
|
||||
def test_help(self):
|
||||
required = [
|
||||
'.*?^usage: ',
|
||||
'.*?^\s+help\s+print detailed help for another command'
|
||||
]
|
||||
kb_help, stderr = self.shell('help')
|
||||
for r in required:
|
||||
self.assertThat((kb_help + stderr),
|
||||
matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE))
|
133
kingbirdclient/tests/test_shell.py
Normal file
133
kingbirdclient/tests/test_shell.py
Normal file
@ -0,0 +1,133 @@
|
||||
# Copyright 2016 EricssonAB.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from kingbirdclient.tests import base_shell_test as base
|
||||
|
||||
|
||||
class TestShell(base.BaseShellTests):
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.determine_client_version')
|
||||
def test_kingbird_version(self, mock):
|
||||
self.shell(
|
||||
'--os-kingbird-version=v1 quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
kingbird_version = mock.call_args
|
||||
self.assertEqual('v1', kingbird_version[0][0])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.determine_client_version')
|
||||
def test_default_kingbird_version(self, mock):
|
||||
default_version = 'v1.0'
|
||||
self.shell('quota-defaults')
|
||||
self.assertTrue(mock.called)
|
||||
kingbird_version = mock.call_args
|
||||
self.assertEqual(default_version, kingbird_version[0][0])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_env_variables(self, mock):
|
||||
self.shell(
|
||||
'--os-auth-url=https://127.0.0.1:35357/v3 '
|
||||
'--os-username=admin '
|
||||
'--os-password=1234 '
|
||||
'--os-tenant-name=admin '
|
||||
'quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('https://127.0.0.1:35357/v3', params[1]['auth_url'])
|
||||
self.assertEqual('admin', params[1]['username'])
|
||||
self.assertEqual('admin', params[1]['project_name'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_env_without_auth_url(self, mock):
|
||||
self.shell(
|
||||
'--os-username=admin '
|
||||
'--os-password=1234 '
|
||||
'--os-tenant-name=admin '
|
||||
'quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('', params[1]['auth_url'])
|
||||
self.assertEqual('admin', params[1]['username'])
|
||||
self.assertEqual('admin', params[1]['project_name'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_kb_service_type(self, mock):
|
||||
self.shell('--os-service-type=synchronization')
|
||||
self.assertTrue(mock.called)
|
||||
parameters = mock.call_args
|
||||
self.assertEqual('synchronization', parameters[1]['service_type'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_kb_default_service_type(self, mock):
|
||||
self.shell('quota-defaults')
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
# Default service type is synchronization
|
||||
self.assertEqual('synchronization', params[1]['service_type'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_kb_endpoint_type(self, mock):
|
||||
self.shell('--os-kingbird-endpoint-type=adminURL quota-defaults')
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('adminURL', params[1]['endpoint_type'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_kb_default_endpoint_type(self, mock):
|
||||
self.shell('quota-defaults')
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('publicURL', params[1]['endpoint_type'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_os_auth_token(self, mock):
|
||||
self.shell(
|
||||
'--os-auth-token=abcd1234 '
|
||||
'quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('abcd1234', params[1]['auth_token'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_command_without_kingbird_url(self, mock):
|
||||
self.shell(
|
||||
'quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('', params[1]['kingbird_url'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_command_with_kingbird_url(self, mock):
|
||||
self.shell(
|
||||
'--os-kingbird-url=http://localhost:8118/v1 quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('http://localhost:8118/v1',
|
||||
params[1]['kingbird_url'])
|
||||
|
||||
@mock.patch('kingbirdclient.api.client.client')
|
||||
def test_command_without_project_name(self, mock):
|
||||
self.shell(
|
||||
'quota-defaults'
|
||||
)
|
||||
self.assertTrue(mock.called)
|
||||
params = mock.call_args
|
||||
self.assertEqual('', params[1]['project_name'])
|
@ -23,6 +23,10 @@ classifier =
|
||||
packages =
|
||||
kingbirdclient
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
kingbird = kingbirdclient.shell:main
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
@ -48,4 +52,4 @@ output_file = kingbirdclient/locale/kingbirdclient.pot
|
||||
[build_releasenotes]
|
||||
all_files = 1
|
||||
build-dir = releasenotes/build
|
||||
source-dir = releasenotes/source
|
||||
source-dir = releasenotes/source
|
||||
|
Loading…
x
Reference in New Issue
Block a user