update host api & cli

- update host add, remove api
- new apis for host setup, ssh_check, get_hosts, get_groups
- new exception classes
- update host cli commands to use new apis

Jira-Issue: OSTACKDEV-16
This commit is contained in:
Steve Noyes 2016-03-21 13:41:17 -04:00
parent 5a1596f051
commit b883423d67
19 changed files with 307 additions and 177 deletions

View File

@ -13,8 +13,13 @@
# under the License.
import logging
import kollacli.i18n as u
from kollacli.api.exceptions import InvalidArgument
from kollacli.api.job import Job
from kollacli.common.ansible import actions
from kollacli.common.inventory import Inventory
from kollacli.common.utils import safe_decode
LOG = logging.getLogger(__name__)
@ -49,6 +54,15 @@ class AsyncApi(object):
Stops and removes all kolla related docker containers on the
specified hosts.
"""
if destroy_type not in ['stop', 'kill']:
raise InvalidArgument(
u._('Invalid destroy type ({type}). Must be either '
'"stop" or "kill".').format(type=destroy_type))
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
inventory.validate_hostnames(hostnames)
ansible_job = actions.destroy_hosts(hostnames, destroy_type,
verbose_level, include_data)
return Job(ansible_job)
@ -60,5 +74,9 @@ class AsyncApi(object):
any of the hosts are not configured correctly or if they have
already been deployed to.
"""
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
inventory.validate_hostnames(hostnames)
ansible_job = actions.precheck(hostnames, verbose_level)
return Job(ansible_job)

View File

@ -0,0 +1,79 @@
# Copyright(c) 2016, Oracle and/or its affiliates. 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.
"""Exception definitions."""
import kollacli.i18n as u
class ClientException(Exception):
"""KollaClient Base Class Exception"""
def __init__(self, message, *args):
if not message:
message = u._('An unknown exception occurred.')
super(ClientException, self).__init__(message, *args)
class NotInInventory(ClientException):
"""Not in inventory exception"""
def __init__(self, obj_type, obj_names, *args):
if isinstance(obj_names, list):
# list of names
invalid_objs = ''
comma = ''
for obj_name in obj_names:
invalid_objs = ''.join([invalid_objs, comma, obj_name])
comma = ','
else:
# single object name
invalid_objs = obj_names
message = (u._('{type} ({objs}) does not exist.')
.format(type=obj_type, objs=invalid_objs))
super(NotInInventory, self).__init__(message, *args)
class HostError(ClientException):
pass
class HostsSshCheckError(ClientException):
def __init__(self, hostnames, *args):
failed_hosts = ''
comma = ''
for hostname in hostnames:
failed_hosts = ''.join([failed_hosts, comma, hostname])
comma = ','
message = (u._('host(s) ssh check failed: {hosts}')
.format(hosts=failed_hosts))
super(HostsSshCheckError, self).__init__(message, *args)
class InvalidArgument(ClientException):
"""Invalid argument"""
pass
class InvalidConfiguration(ClientException):
"""Invalid configuration"""
pass
class FailedOperation(ClientException):
pass
class MissingArgument(ClientException):
"""Missing argument"""
def __init__(self, argname, *args):
message = (u._('argument is missing: {name}')
.format(name=argname))
super(InvalidArgument, self).__init__(message, *args)

View File

@ -13,26 +13,92 @@
# under the License.
import logging
from kollacli.api.exceptions import MissingArgument
from kollacli.common.inventory import Inventory
from kollacli.common.utils import safe_decode
LOG = logging.getLogger(__name__)
class HostApi(object):
def host_add(self, hostname):
def host_add(self, hostnames):
"""add hosts to the inventory"""
if not hostnames:
raise MissingArgument('host names')
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
inventory.add_host(hostname)
for hostname in hostnames:
inventory.add_host(hostname)
Inventory.save(inventory)
def host_remove(self, hostname):
# TODO(bmace) - need to do a lot of validity
# / null checking in these api calls
def host_remove(self, hostnames):
"""remove hosts from the inventory"""
inventory = Inventory.load()
if hostname.lower() == 'all':
inventory.remove_all_hosts()
else:
if not hostnames:
raise MissingArgument('host name')
hostnames = safe_decode(hostnames)
for hostname in hostnames:
inventory.remove_host(hostname)
Inventory.save(inventory)
def host_get_all(self):
"""get all hosts in the inventory"""
# TODO(snoyes) - need to make a host object
inventory = Inventory.load()
hostnames = inventory.get_hostnames()
return hostnames
def host_get_groups(self, hostname=None):
"""get groups for hosts
Return:
- if hostname, {hostname: [groups]}
- else, {hostname: [groups], hostname: [groups]...}
"""
inventory = Inventory.load()
host_groups = inventory.get_host_groups()
if hostname:
hostname = safe_decode(hostname)
inventory.validate_hostnames([hostname])
groupnames = host_groups[hostname]
host_groups = {hostname: groupnames}
return host_groups
def host_check_ssh(self, hostnames):
"""ssh check for hosts
return {hostname: {'success': True|False,
'msg': message}}
"""
inventory = Inventory.load()
hostnames = safe_decode(hostnames)
inventory.validate_hostnames(hostnames)
summary = inventory.ssh_check_hosts(hostnames)
return summary
def host_setup_hosts(self, hosts_info):
"""setup multiple hosts
hosts_info is a dict of format:
{'hostname1': {
'password': password
'uname': user_name
}
}
The uname entry is optional.
"""
inventory = Inventory.load()
inventory.validate_hostnames(hosts_info.keys())
inventory.setup_hosts(hosts_info)
def host_setup(self, hostname, password):
# TODO(snoyes) move to host object
inventory = Inventory.load()
hostname = safe_decode(hostname)
inventory.validate_hostnames([hostname])
inventory.setup_host(hostname, password)

View File

@ -17,8 +17,8 @@ import traceback
import kollacli.i18n as u
from kollacli.api.client import ClientApi
from kollacli.commands.exceptions import CommandError
from kollacli.common.utils import convert_to_unicode
from kollacli.exceptions import CommandError
from cliff.command import Command

View File

@ -16,6 +16,9 @@ import kollacli.i18n as u
class CommandError(Exception):
"""CLI command error"""
def __init__(self, message, *args):
message = u._('ERROR: {message}').format(message=message)
prefix = u._('ERROR: ')
if not message.startswith(prefix):
message = prefix + message
super(CommandError, self).__init__(message, *args)

View File

@ -15,9 +15,9 @@ import traceback
import kollacli.i18n as u
from kollacli.commands.exceptions import CommandError
from kollacli.common.inventory import Inventory
from kollacli.common.utils import convert_to_unicode
from kollacli.exceptions import CommandError
from cliff.command import Command
from cliff.lister import Lister

View File

@ -21,11 +21,8 @@ import yaml
import kollacli.i18n as u
from kollacli.api.client import ClientApi
# TODO(snoyes): remove inventory reference from CLI
from kollacli.common.inventory import Inventory
from kollacli.common.utils import convert_to_unicode
from kollacli.common.utils import get_setup_user
from kollacli.exceptions import CommandError
from kollacli.api.exceptions import ClientException
from kollacli.commands.exceptions import CommandError
from cliff.command import Command
from cliff.lister import Lister
@ -34,12 +31,6 @@ LOG = logging.getLogger(__name__)
CLIENT = ClientApi()
def _host_not_found(hostname):
raise CommandError(
u._('Host ({host}) not found. Please add it with "host add".')
.format(host=hostname))
class HostAdd(Command):
"""Add host to openstack-kolla."""
@ -52,17 +43,10 @@ class HostAdd(Command):
def take_action(self, parsed_args):
try:
hostname = parsed_args.hostname.strip()
hostname = convert_to_unicode(hostname)
CLIENT.host_add([hostname])
if hostname.lower() == 'all':
raise CommandError(
u._('Special host name "all" cannot be added as an '
'individual host.'))
CLIENT.host_add(hostname)
except CommandError as e:
raise e
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
raise Exception(traceback.format_exc())
@ -86,17 +70,11 @@ class HostDestroy(Command):
def take_action(self, parsed_args):
try:
hostname = ''
hostname = parsed_args.hostname.strip()
hostname = convert_to_unicode(hostname)
inventory = Inventory.load()
hostnames = [hostname]
if hostname == 'all':
hostnames = inventory.get_hostnames()
else:
if not inventory.get_host(hostname):
_host_not_found(hostname)
hostnames = CLIENT.host_get_all()
destroy_type = 'kill'
if parsed_args.stop:
@ -118,8 +96,8 @@ class HostDestroy(Command):
raise CommandError(u._('Job failed:\n{msg}')
.format(msg=job.get_error_message()))
except CommandError as e:
raise e
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
raise Exception(traceback.format_exc())
@ -129,19 +107,20 @@ class HostRemove(Command):
def get_parser(self, prog_name):
parser = super(HostRemove, self).get_parser(prog_name)
parser.add_argument('hostname', metavar='<hostname>',
help=u._('Host name'))
parser.add_argument('hostname', metavar='<hostname | all>',
help=u._('Host name or "all"'))
return parser
def take_action(self, parsed_args):
try:
hostname = parsed_args.hostname.strip()
hostname = convert_to_unicode(hostname)
hostnames = [hostname]
if hostname == 'all':
hostnames = CLIENT.host_get_all()
CLIENT.host_remove(hostnames)
CLIENT.host_remove(hostname)
except CommandError as e:
raise e
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
raise Exception(traceback.format_exc())
@ -163,28 +142,19 @@ class HostList(Lister):
hostname = None
if parsed_args.hostname:
hostname = parsed_args.hostname.strip()
hostname = convert_to_unicode(hostname)
inventory = Inventory.load()
if hostname:
host = inventory.get_host(hostname)
if not host:
_host_not_found(hostname)
host_groups = CLIENT.host_get_groups(hostname)
data = []
host_groups = inventory.get_host_groups()
if host_groups:
if hostname:
data.append((hostname, host_groups[hostname]))
else:
for (hostname, groupnames) in host_groups.items():
data.append((hostname, groupnames))
for (hostname, groupnames) in host_groups.items():
data.append((hostname, groupnames))
else:
data.append(('', ''))
return ((u._('Host'), u._('Groups')), sorted(data))
except CommandError as e:
raise e
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
raise Exception(traceback.format_exc())
@ -194,7 +164,7 @@ class HostCheck(Command):
def get_parser(self, prog_name):
parser = super(HostCheck, self).get_parser(prog_name)
parser.add_argument('hostname', metavar='<hostname>',
parser.add_argument('hostname', metavar='<hostname | all>',
help=u._('Host name or "all"'))
parser.add_argument('--predeploy', action='store_true',
help=u._('Run pre-deploy host checks.'))
@ -203,14 +173,9 @@ class HostCheck(Command):
def take_action(self, parsed_args):
try:
hostname = parsed_args.hostname.strip()
hostname = convert_to_unicode(hostname)
inventory = Inventory.load()
hostnames = [hostname]
if hostname == 'all':
hostnames = inventory.get_hostnames()
else:
if not inventory.get_host(hostname):
_host_not_found(hostname)
hostnames = CLIENT.host_get_all()
if parsed_args.predeploy:
# run pre-deploy checks
@ -224,24 +189,23 @@ class HostCheck(Command):
if status != 0:
raise CommandError(u._('Job failed:\n{msg}')
.format(msg=job.get_error_message()))
else:
# run ssh checks
summary = CLIENT.host_check_ssh(hostnames)
all_ok = True
summary = inventory.ssh_check_hosts(hostnames)
for hostname, info in summary.items():
status = 'success'
status = u._('success')
msg = ''
if not info['success']:
status = 'failed- '
status = u._('failed- ')
msg = info['msg']
all_ok = False
LOG.info('Host (%s): %s %s' % (hostname, status, msg))
LOG.info(u._('Host {host}: {sts} {msg}')
.format(host=hostname, sts=status, msg=msg))
if not all_ok:
raise CommandError('Host check failed.')
except CommandError as e:
raise e
raise CommandError(u._('Host check failed.'))
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
raise Exception(traceback.format_exc())
@ -268,21 +232,16 @@ class HostSetup(Command):
raise CommandError(
u._('Host name and hosts info file path '
'cannot both be present.'))
inventory = Inventory.load()
if parsed_args.file:
# multi-host setup via xml file
hosts_data = self.get_yml_data(parsed_args.file.strip())
inventory.setup_hosts(hosts_data)
CLIENT.host_setup_hosts(hosts_data)
else:
# single host setup
hostname = parsed_args.hostname.strip()
hostname = convert_to_unicode(hostname)
if not inventory.get_host(hostname):
_host_not_found(hostname)
check_ok, _ = inventory.ssh_check_host(hostname)
if check_ok:
summary = CLIENT.host_check_ssh([hostname])
if summary[hostname]['success']:
LOG.info(
u._LI('Skipping setup of host ({host}) as '
'ssh check is ok.').format(host=hostname))
@ -291,15 +250,13 @@ class HostSetup(Command):
if parsed_args.insecure:
password = parsed_args.insecure.strip()
else:
setup_user = get_setup_user()
password = getpass.getpass(
u._('{user} password for {host}: ')
.format(user=setup_user, host=hostname))
password = convert_to_unicode(password)
inventory.setup_host(hostname, password)
u._('kolla password for {host}: ')
.format(host=hostname))
CLIENT.host_setup(hostname, password)
except CommandError as e:
raise e
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
raise Exception(traceback.format_exc())

View File

@ -20,10 +20,10 @@ import kollacli.i18n as u
from cliff.command import Command
from cliff.lister import Lister
from kollacli.commands.exceptions import CommandError
from kollacli.common.passwords import clear_password
from kollacli.common.passwords import get_password_names
from kollacli.common.passwords import set_password
from kollacli.exceptions import CommandError
class PasswordSet(Command):

View File

@ -15,9 +15,9 @@ import traceback
import kollacli.i18n as u
from kollacli.commands.exceptions import CommandError
from kollacli.common import properties
from kollacli.common import utils
from kollacli.exceptions import CommandError
from cliff.command import Command
from cliff.lister import Lister

View File

@ -15,9 +15,9 @@ import traceback
import kollacli.i18n as u
from kollacli.commands.exceptions import CommandError
from kollacli.common.inventory import Inventory
from kollacli.common.utils import convert_to_unicode
from kollacli.exceptions import CommandError
from cliff.command import Command
from cliff.lister import Lister

View File

@ -19,7 +19,7 @@ from cliff.command import Command
import kollacli.i18n as u
from kollacli.api.client import ClientApi
from kollacli.exceptions import CommandError
from kollacli.commands.exceptions import CommandError
CLIENT = ClientApi()

View File

@ -16,6 +16,9 @@ import os
import kollacli.i18n as u
from kollacli.api.exceptions import InvalidArgument
from kollacli.api.exceptions import InvalidConfiguration
from kollacli.api.exceptions import NotInInventory
from kollacli.common.ansible.playbook import AnsiblePlaybook
from kollacli.common.inventory import Inventory
from kollacli.common import properties
@ -24,7 +27,6 @@ from kollacli.common.utils import get_kolla_etc
from kollacli.common.utils import get_kolla_home
from kollacli.common.utils import get_kollacli_home
from kollacli.common.utils import is_string_true
from kollacli.exceptions import CommandError
LOG = logging.getLogger(__name__)
@ -37,11 +39,6 @@ def destroy_hosts(hostnames, destroy_type,
or killed. That will be determined by the destroy_type,
which can either be 'stop' or 'kill'.
'''
if destroy_type not in ['stop', 'kill']:
raise CommandError(
u._('Invalid destroy type ({type}). Must be either '
'"stop" or "kill".').format(type=destroy_type))
playbook_name = 'host_destroy_no_data.yml'
if include_data:
playbook_name = 'host_destroy.yml'
@ -125,7 +122,7 @@ def _run_deploy_rules(playbook):
# cannot have both groups and hosts
if playbook.hosts and playbook.groups:
raise CommandError(
raise InvalidArgument(
u._('Hosts and Groups arguments cannot '
'both be present at the same time.'))
@ -134,8 +131,7 @@ def _run_deploy_rules(playbook):
for service in playbook.services:
valid_service = inventory.get_service(service)
if not valid_service:
raise CommandError(u._('Service ({srvc}) not found.')
.format(srvc=service))
raise NotInInventory(u._('Service'), service)
# check that every group with enabled services
# has hosts associated to it
@ -160,7 +156,7 @@ def _run_deploy_rules(playbook):
failed_groups.append(groupname)
if len(failed_groups) > 0:
raise CommandError(
raise InvalidConfiguration(
u._('Deploy failed. '
'Groups: {groups} with enabled '
'services : {services} '
@ -184,4 +180,4 @@ def _run_deploy_rules(playbook):
'not yet been set up. Please see the '
'documentation for swift configuration '
'instructions.')
raise CommandError(msg)
raise InvalidConfiguration(msg)

View File

@ -18,11 +18,11 @@ import traceback
import kollacli.i18n as u
from kollacli.api.exceptions import NotInInventory
from kollacli.common.ansible.job import AnsibleJob
from kollacli.common.utils import get_admin_user
from kollacli.common.utils import get_ansible_command
from kollacli.common.utils import get_kolla_etc
from kollacli.exceptions import CommandError
from kollacli.common.inventory import Inventory
@ -114,15 +114,13 @@ class AnsiblePlaybook(object):
for hostname in self.hosts:
host = self.inventory.get_host(hostname)
if not host:
raise CommandError(u._('Host ({host}) not found.')
.format(host=hostname))
raise NotInInventory(u._('Host'), hostname)
inventory_filter['deploy_hosts'] = self.hosts
elif self.groups:
for groupname in self.groups:
group = self.inventory.get_group(groupname)
if not group:
raise CommandError(u._('Group ({group}) not found.')
.format(group=groupname))
raise NotInInventory(u._('Group'), groupname)
inventory_filter['deploy_groups'] = self.groups
inventory_path = \
self.inventory.create_json_gen_file(inventory_filter)

View File

@ -21,6 +21,12 @@ import uuid
import kollacli.i18n as u
from kollacli.api.exceptions import FailedOperation
from kollacli.api.exceptions import HostError
from kollacli.api.exceptions import InvalidArgument
from kollacli.api.exceptions import InvalidConfiguration
from kollacli.api.exceptions import MissingArgument
from kollacli.api.exceptions import NotInInventory
from kollacli.common.sshutils import ssh_setup_host
from kollacli.common.utils import get_admin_user
from kollacli.common.utils import get_ansible_command
@ -31,8 +37,6 @@ from kollacli.common.utils import run_cmd
from kollacli.common.utils import sync_read_file
from kollacli.common.utils import sync_write_file
from kollacli.exceptions import CommandError
ANSIBLE_SSH_USER = 'ansible_ssh_user'
ANSIBLE_CONNECTION = 'ansible_connection'
ANSIBLE_BECOME = 'ansible_become'
@ -336,7 +340,7 @@ class Inventory(object):
else:
inventory = Inventory()
except Exception:
raise CommandError(
raise FailedOperation(
u._('Loading inventory failed. : {error}')
.format(error=traceback.format_exc()))
return inventory
@ -353,7 +357,7 @@ class Inventory(object):
sync_write_file(inventory_path, pretty_data)
except Exception as e:
raise CommandError(
raise FailedOperation(
u._('Saving inventory failed. : {error}')
.format(error=str(e)))
@ -397,17 +401,14 @@ class Inventory(object):
if group name is not none, add host to group
"""
if groupname and groupname not in self._groups:
raise CommandError(
u._('Group name ({group}) does not exist.')
.format(group=groupname))
raise NotInInventory(u._('Group'), groupname)
if groupname and hostname not in self._hosts:
raise CommandError(
u._('Host name ({host}) does not exist.')
.format(host=hostname))
# if a groupname is specified, the host must already exist
raise NotInInventory(u._('Host'), hostname)
if not groupname and not self.remote_mode and len(self._hosts) >= 1:
raise CommandError(
raise InvalidConfiguration(
u._('Cannot have more than one host when in local deploy '
'mode.'))
@ -436,9 +437,7 @@ class Inventory(object):
if group name is not none, remove host from group
"""
if groupname and groupname not in self._groups:
raise CommandError(
u._('Group name ({group}) does not exist.')
.format(group=groupname))
raise NotInInventory(u._('Group'), groupname)
if hostname not in self._hosts:
return
@ -488,7 +487,7 @@ class Inventory(object):
summary = '\n'
for hostname, err in failed_hosts.items():
summary = summary + '- %s: %s\n' % (hostname, err)
raise CommandError(
raise HostError(
u._('Not all hosts were set up. : {reasons}')
.format(reasons=summary))
else:
@ -507,7 +506,7 @@ class Inventory(object):
LOG.info(u._LI('Host ({host}) setup succeeded.')
.format(host=hostname))
except Exception as e:
raise CommandError(
raise HostError(
u._('Host ({host}) setup failed : {error}')
.format(host=hostname, error=str(e)))
return True
@ -559,7 +558,7 @@ class Inventory(object):
# Group names cannot overlap with service names:
if groupname in self._services or groupname in self._sub_services:
raise CommandError(
raise InvalidArgument(
u._('Invalid group name. A service name '
'cannot be used for a group name.'))
@ -574,7 +573,7 @@ class Inventory(object):
def remove_group(self, groupname):
if groupname in PROTECTED_GROUPS:
raise CommandError(
raise InvalidArgument(
u._('Cannot remove {group} group. It is required by kolla.')
.format(group=groupname))
@ -617,7 +616,7 @@ class Inventory(object):
return groups
def get_host_groups(self):
"""return { hostname : groupnames }"""
"""return { hostname : [groupnames] }"""
host_groups = {}
for host in self._hosts.values():
@ -676,8 +675,7 @@ class Inventory(object):
def add_group_to_service(self, groupname, servicename):
if groupname not in self._groups:
raise CommandError(u._('Group ({group}) not found.')
.format(group=groupname))
raise NotInInventory(u._('Group'), groupname)
if servicename in self._services:
service = self.get_service(servicename)
service.add_groupname(groupname)
@ -685,13 +683,11 @@ class Inventory(object):
sub_service = self.get_sub_service(servicename)
sub_service.add_groupname(groupname)
else:
raise CommandError(u._('Service ({service})) not found.')
.format(service=servicename))
raise NotInInventory(u._('Service'), servicename)
def remove_group_from_service(self, groupname, servicename):
if groupname not in self._groups:
raise CommandError(u._('Group ({group}) not found.')
.format(group=groupname))
raise NotInInventory(u._('Group'), groupname)
if servicename in self._services:
service = self.get_service(servicename)
service.remove_groupname(groupname)
@ -699,8 +695,7 @@ class Inventory(object):
sub_service = self.get_sub_service(servicename)
sub_service.remove_groupname(groupname)
else:
raise CommandError(u._('Service ({service})) not found.')
.format(service=servicename))
raise NotInInventory(u._('Service'), servicename)
def create_sub_service(self, sub_servicename):
if sub_servicename not in self._sub_services:
@ -750,7 +745,7 @@ class Inventory(object):
def set_deploy_mode(self, remote_flag):
if not remote_flag and len(self._hosts) > 1:
raise CommandError(
raise InvalidConfiguration(
u._('Cannot set local deploy mode when multiple hosts exist.'))
self.remote_mode = remote_flag
@ -887,3 +882,13 @@ class Inventory(object):
def remove_json_gen_file(self, path):
remove_temp_inventory(path)
def validate_hostnames(self, hostnames):
if not hostnames:
raise MissingArgument(u._('host name(s)'))
invalid_hosts = []
for hostname in hostnames:
if hostname not in self._hosts:
invalid_hosts.append(hostname)
if invalid_hosts:
raise NotInInventory(u._('Host'), invalid_hosts)

View File

@ -15,8 +15,8 @@ import os
import kollacli.i18n as u
from kollacli.api.exceptions import FailedOperation
from kollacli.common import utils
from kollacli.exceptions import CommandError
PWDS_FILENAME = 'passwords.yml'
PWD_EDITOR_FILENAME = 'passwd_editor.py'
@ -31,7 +31,7 @@ def set_password(pwd_key, pwd_value):
cmd = '%s -k %s -v %s' % (_get_cmd_prefix(), pwd_key, pwd_value)
err_msg, output = utils.run_cmd(cmd, print_output=False)
if err_msg:
raise CommandError(
raise FailedOperation(
u._('Password set failed. {error} {message}')
.format(error=err_msg, message=output))
@ -44,7 +44,7 @@ def clear_password(pwd_key):
cmd = '%s -k %s -c' % (_get_cmd_prefix(), pwd_key)
err_msg, output = utils.run_cmd(cmd, print_output=False)
if err_msg:
raise CommandError('%s %s' % (err_msg, output))
raise FailedOperation('%s %s' % (err_msg, output))
def get_password_names():
@ -52,7 +52,7 @@ def get_password_names():
cmd = '%s -l' % (_get_cmd_prefix())
err_msg, output = utils.run_cmd(cmd, print_output=False)
if err_msg:
raise CommandError('%s %s' % (err_msg, output))
raise FailedOperation('%s %s' % (err_msg, output))
pwd_names = []
if output and ',' in output:

View File

@ -18,13 +18,13 @@ import yaml
import kollacli.i18n as u
from kollacli.api.exceptions import NotInInventory
from kollacli.common.inventory import Inventory
from kollacli.common.utils import change_property
from kollacli.common.utils import get_group_vars_dir
from kollacli.common.utils import get_host_vars_dir
from kollacli.common.utils import get_kolla_home
from kollacli.common.utils import sync_read_file
from kollacli.exceptions import CommandError
LOG = logging.getLogger(__name__)
@ -185,9 +185,7 @@ class AnsibleProperties(object):
for host_name in host_list:
host = inventory.get_host(host_name)
if host is None:
raise CommandError(
u._('Host {host} does not exist.')
.format(host=host_name))
raise NotInInventory(u._('Host'), host_name)
if host_name in self.host_props:
prop_list += self.host_props[host_name]
else:
@ -204,9 +202,7 @@ class AnsibleProperties(object):
for group_name in group_list:
group = inventory.get_group(group_name)
if group is None:
raise CommandError(
u._('Group {group} does not exist.')
.format(group=group_name))
raise NotInInventory(u._('Group'), group_name)
if group_name in self.group_props:
prop_list += self.group_props[group_name]
else:
@ -264,9 +260,7 @@ class AnsibleProperties(object):
for host_name in hosts:
host = inventory.get_host(host_name)
if host is None:
raise CommandError(
u._('Host {host} does not exist.')
.format(host=host_name))
raise NotInInventory(u._('Host'), host_name)
host_list.append(host)
try:
for host in host_list:
@ -286,9 +280,7 @@ class AnsibleProperties(object):
for group_name in groups:
group = inventory.get_group(group_name)
if group is None:
raise CommandError(
u._('Group {group} does not exist.')
.format(group=group_name))
raise NotInInventory(u._('Group'), group_name)
group_list.append(group)
try:
for group in group_list:
@ -315,9 +307,7 @@ class AnsibleProperties(object):
for host_name in hosts:
host = inventory.get_host(host_name)
if host is None:
raise CommandError(
u._('Host {host} does not exist.')
.format(host=host_name))
raise NotInInventory(u._('Host'), host_name)
host_list.append(host)
try:
for host in host_list:
@ -337,9 +327,7 @@ class AnsibleProperties(object):
for group_name in groups:
group = inventory.get_group(group_name)
if group is None:
raise CommandError(
u._('Group {group} does not exist.')
.format(group=group_name))
raise NotInInventory(u._('Group'), group_name)
group_list.append(group)
try:
for group in group_list:

View File

@ -22,7 +22,7 @@ import sys
import kollacli.i18n as u
from kollacli.exceptions import CommandError
from kollacli.api.exceptions import InvalidArgument
LOG = logging.getLogger(__name__)
@ -69,7 +69,7 @@ def get_kolla_log_file_size():
try:
size = int(size_str)
except Exception:
raise CommandError(
raise InvalidArgument(
u._('Environmental variable ({env_var}) is not an '
'integer ({log_size}).')
.format(env_var=envvar, log_size=size_str))
@ -82,7 +82,7 @@ def get_property_list_length():
try:
length = int(length_str)
except Exception:
raise CommandError(
raise InvalidArgument(
u._('Environmental variable ({env_var}) is not an '
'integer ({prop_length}).')
.format(env_var=envvar, prop_length=length_str))
@ -133,6 +133,8 @@ def convert_to_unicode(the_string):
This is used to fixup extended ascii chars in strings. these chars cause
errors in json pickle/unpickle.
"""
if the_string is None:
return the_string
return six.u(the_string)
@ -265,15 +267,32 @@ def sync_write_file(path, data, mode='w'):
raise e
def safe_decode(text):
"""Convert bytes or string to unicode string"""
if text is not None:
def safe_decode(obj_to_decode):
"""Convert bytes or string to unicode string
Convert either a string or list of strings to
unicode.
"""
if obj_to_decode is None:
return None
new_obj = None
if isinstance(obj_to_decode, list):
new_obj = []
for text in obj_to_decode:
try:
text = text.decode('utf-8')
except AttributeError: # nosec
# py3 will raise if text is already a string
pass
new_obj.append(text)
else:
try:
text = text.decode('utf-8')
new_obj = obj_to_decode.decode('utf-8')
except AttributeError: # nosec
# py3 will raise if text is already a string
pass
return text
new_obj = obj_to_decode
return new_obj
def is_string_true(string):

View File

@ -21,11 +21,11 @@ from cliff.commandmanager import CommandManager
import kollacli.i18n as u
from kollacli.commands.exceptions import CommandError
from kollacli.common.inventory import INVENTORY_PATH
from kollacli.common.utils import get_kolla_log_dir
from kollacli.common.utils import get_kolla_log_file_size
from kollacli.common.utils import get_kollacli_etc
from kollacli.exceptions import CommandError
LOG = logging.getLogger(__name__)

View File

@ -159,7 +159,8 @@ class TestFunctional(KollaCliTest):
# no hostname and no file spec
msg = self.run_cli_cmd('host setup', True)
self.assertIn('ERROR', msg, 'No command params did not error')
self.assertIn('ERROR', msg,
'Setup with no command params did not error')
# hostname and file spec both present
msg = self.run_cli_cmd('host setup -f zzzzz hostname', True)