Ejemplo n.º 1
0
 def get_parser(self, prog_name):
     parser = super(Stop, self).get_parser(prog_name)
     parser.add_argument('--hosts',
                         nargs='?',
                         metavar='<host_list>',
                         help=u._('Stop host list'))
     parser.add_argument('--services',
                         nargs='?',
                         metavar='<service_list>',
                         help=u._('Stop service list'))
     return parser
Ejemplo n.º 2
0
 def get_parser(self, prog_name):
     parser = super(HostDestroy, self).get_parser(prog_name)
     parser.add_argument('hostname', metavar='<hostname | all>',
                         help=u._('Host name or ip address or "all"'))
     parser.add_argument('--stop', action='store_true',
                         help=u._('Stop rather than kill'))
     parser.add_argument('--includedata', action='store_true',
                         help=u._('Destroy data containers'))
     parser.add_argument('--removeimages', action='store_true',
                         help=u._('Remove docker images'))
     return parser
Ejemplo n.º 3
0
 def get_parser(self, prog_name):
     parser = super(PasswordSetKey, self).get_parser(prog_name)
     parser.add_argument('passwordname',
                         metavar='<passwordname>',
                         help=u._('Password name'))
     parser.add_argument('privatekeypath',
                         metavar='<privatekeypath>',
                         help=u._('Path to private key file'))
     parser.add_argument('publickeypath',
                         metavar='<publickeypath>',
                         help=u._('Path to public key file'))
     return parser
Ejemplo n.º 4
0
    def take_action(self, parsed_args):
        hosts = None
        serial_flag = False
        verbose_level = self.app.options.verbose_level
        timeout_target = 0
        services = None
        try:
            if parsed_args.hosts:
                host_list = parsed_args.hosts.strip()
                hosts = host_list.split(',')
            if parsed_args.serial:
                serial_flag = True
            if parsed_args.timeout:
                try:
                    timeout = float(parsed_args.timeout[0])
                except Exception:
                    raise CommandError(u._('Timeout value is not a number.'))
                timeout_target = time.time() + (60 * timeout)
            if parsed_args.services:
                service_list = parsed_args.services.strip()
                services = service_list.split(',')

            # if we are doing a targeted host deploy make sure we are doing it
            # to only compute nodes
            if hosts:
                invalid_host_list = []
                compute_group = CLIENT.group_get(['compute'])[0]
                compute_hosts = compute_group.get_hosts()
                for host in hosts:
                    if host not in compute_hosts:
                        invalid_host_list.append(host)
                if len(invalid_host_list) > 0:
                    raise CommandError(
                        u._('Invalid hosts for host targeted deploy. '
                            'Hosts must be in the compute group only.'
                            'Invalid hosts: {hosts}').format(
                                hosts=invalid_host_list))

            job = CLIENT.deploy(hosts, serial_flag, verbose_level, services)

            # wait for job to complete
            status = None
            while status is None:
                if timeout_target and time.time() > timeout_target:
                    job.kill()
                    raise CommandError(u._('Job timed out and was killed.'))
                time.sleep(1)
                status = job.get_status()

            # job is done
            handers_action_result(job, status, verbose_level)
        except Exception:
            raise Exception(traceback.format_exc())
Ejemplo n.º 5
0
    def take_action(self, parsed_args):
        try:
            password_names = CLIENT.password_get_names()
            password_names = sorted(password_names)

            data = []
            for password_name in password_names:
                data.append((password_name, '-'))

            return ((u._('Password Name'), u._('Password')), data)
        except Exception:
            raise Exception(traceback.format_exc())
Ejemplo n.º 6
0
    def _get_yml_data(self, yml_path):
        if not os.path.isfile(yml_path):
            raise CommandError(
                u._('No file exists at {path}. An absolute file path is '
                    'required.').format(path=yml_path))

        with open(yml_path, 'r') as hosts_file:
            file_data = hosts_file.read()

        hosts_info = yaml.safe_load(file_data)
        if not hosts_info:
            raise CommandError(u._('{path} is empty.').format(path=yml_path))
        return hosts_info
Ejemplo n.º 7
0
    def validate_servicenames(self, servicenames, client_filter=False):
        if not servicenames:
            raise MissingArgument(u._('Service name(s)'))
        invalid_services = []
        if client_filter:
            services = self._client_filtered_service_dict()
        else:
            services = self._services

        for service_name in servicenames:
            if service_name not in services:
                invalid_services.append(service_name)
        if invalid_services:
            raise NotInInventory(u._('Service'), invalid_services)
Ejemplo n.º 8
0
 def get_parser(self, prog_name):
     parser = super(Deploy, self).get_parser(prog_name)
     parser.add_argument('--hosts',
                         nargs='?',
                         metavar='<host_list>',
                         help=u._('Deployment host list'))
     parser.add_argument('--serial',
                         action='store_true',
                         help=u._('Deploy serially'))
     parser.add_argument('--timeout',
                         nargs=1,
                         metavar='<timeout>',
                         help=u._('timeout (in minutes)'))
     return parser
Ejemplo n.º 9
0
 def get_parser(self, prog_name):
     parser = super(PropertyClear, self).get_parser(prog_name)
     parser.add_argument('propertyname',
                         metavar='<propertyname>',
                         help=u._('Property name'))
     parser.add_argument('--hosts',
                         nargs=1,
                         metavar='<host_list>',
                         help=u._('Property host list'))
     parser.add_argument('--groups',
                         nargs=1,
                         metavar='<group_list>',
                         help=u._('Property group list'))
     return parser
Ejemplo n.º 10
0
    def take_action(self, parsed_args):
        try:
            hostname = parsed_args.hostname.strip()

            hostnames = [hostname]
            if hostname == 'all':
                hostnames = _get_all_hostnames()

            destroy_type = 'kill'
            if parsed_args.stop:
                destroy_type = 'stop'
            include_data = False
            if parsed_args.includedata:
                include_data = True
            remove_images = False
            if parsed_args.removeimages:
                remove_images = True

            if not include_data:
                question = ('This will delete all containers and data'
                            ', are you sure? (y/n)')
                answer = raw_input(question)
                while answer != 'y' and answer != 'n':
                    answer = raw_input(question)
                if answer is 'n':
                    LOG.info('Aborting destroy')
                    return
            verbose_level = self.app.options.verbose_level

            job = CLIENT.host_destroy(hostnames, destroy_type,
                                      verbose_level, include_data,
                                      remove_images)
            status = job.wait()
            if verbose_level > 2:
                LOG.info('\n\n' + 80 * '=')
                LOG.info(u._('DEBUG command output:\n{out}')
                         .format(out=job.get_console_output()))
            if status != 0:
                raise CommandError(u._('Job failed:\n{msg}')
                                   .format(msg=job.get_error_message()))
            elif verbose_level > 1:
                # log any ansible warnings
                msg = job.get_error_message()
                if msg:
                    LOG.warn(msg)

        except ClientException as e:
            raise CommandError(str(e))
        except Exception as e:
            raise Exception(traceback.format_exc())
Ejemplo n.º 11
0
    def property_set(self,
                     property_dict,
                     property_type=GLOBAL_TYPE,
                     change_set=None):
        # type: (Dict[str,str], str, List[str]) -> None
        """Set a property

        :param property_dict: property dictionary containing key / values
        :type property_dict: dictionary
        :param property_type: one of 'global', 'group' or 'host'
        :type property_type: string
        :param change_set: for group or host sets this is the list of groups
                           or hosts to set the property for
        :type change_set: list of strings

        """
        ansible_properties = AnsibleProperties()
        for key, value in property_dict.items():
            check_arg(key, u._('Property Key'), str)
            current_property = ansible_properties.get_property(key)
            if current_property is not None:
                current_property_type = current_property.value_type
                if current_property_type is not str:
                    value = yaml.safe_load(value)
                    if current_property.value is None:
                        current_property_type = None
                    check_arg(value,
                              u._('Property Value'),
                              current_property_type,
                              empty_ok=True)
                    property_dict[key] = value
            else:
                check_arg(value, u._('Property Value'), str, empty_ok=True)
            if type(value) is str and '"' in value:
                raise InvalidArgument(
                    u._('Cannot use double quotes in '
                        'a property value.'))

        self._check_type(property_type)
        if property_type is not GLOBAL_TYPE:
            check_arg(change_set, u._('Change Set'), list, none_ok=True)
            change_set = safe_decode(change_set)

        if property_type == GLOBAL_TYPE:
            ansible_properties.set_property(property_dict)
        elif property_type == GROUP_TYPE:
            ansible_properties.set_group_property(property_dict, change_set)
        else:
            ansible_properties.set_host_property(property_dict, change_set)
Ejemplo n.º 12
0
 def take_action(self, parsed_args):
     try:
         data = [('', '')]
         groups = CLIENT.group_get_all()
         if groups:
             data = []
             for group in groups:
                 data.append((group.get_name(),
                              sorted(group.get_services())))
         data = convert_lists_to_string(data, parsed_args)
         return ((u._('Group'), u._('Services')), sorted(data))
     except ClientException as e:
         raise CommandError(str(e))
     except Exception as e:
         raise Exception(traceback.format_exc())
Ejemplo n.º 13
0
    def password_set_sshkey(self, name, private_key, public_key):
        # type: (str, str, str) -> None
        """Set password to an ssh key

        :param name: name of the password
        :type name: string
        :param private_key: ssh private key
        :type value: string
        :param public_key: ssh public key
        :type value: string
        """
        check_arg(name, u._('Password name'), str)
        check_arg(private_key, u._('Private key'), str, display_param=False)
        check_arg(public_key, u._('Public key'), str, display_param=False)
        set_password_sshkey(name, private_key, public_key)
Ejemplo n.º 14
0
    def take_action(self, parsed_args):
        try:
            hostname = parsed_args.hostname.strip()

            hostnames = [hostname]
            if hostname == 'all':
                hostnames = _get_all_hostnames()
                # if there are no hosts, don't bother doing anything
                if not hostnames:
                    return

            destroy_type = 'kill'
            if parsed_args.stop:
                destroy_type = 'stop'
            include_data = False
            if parsed_args.includedata:
                include_data = True
            remove_images = False
            if parsed_args.removeimages:
                remove_images = True

            if include_data and not self._is_ok_to_delete_data():
                LOG.info('Aborting destroy')
                return

            verbose_level = self.app.options.verbose_level

            job = CLIENT.host_destroy(hostnames, destroy_type,
                                      verbose_level, include_data,
                                      remove_images)
            status = job.wait()
            if verbose_level > 2:
                LOG.info('\n\n' + 80 * '=')
                LOG.info(u._('DEBUG command output:\n{out}')
                         .format(out=job.get_console_output()))
            if status != 0:
                raise CommandError(u._('Job failed:\n{msg}')
                                   .format(msg=job.get_error_message()))
            elif verbose_level > 1:
                # log any ansible warnings
                msg = job.get_error_message()
                if msg:
                    LOG.warn(msg)

        except ClientException as e:
            raise CommandError(str(e))
        except Exception as e:
            raise Exception(traceback.format_exc())
Ejemplo n.º 15
0
def run_cmd(cmd, print_output=True):
    """run a system command

    return:
    - err_msg:  empty string=command succeeded
                not None=command failed
    - output:   string: all the output of the run command
    """
    output = None
    try:
        process = subprocess.Popen(
            cmd,
            shell=True,  # nosec
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
        output, err = process.communicate()
    except Exception as e:
        err = str(e)

    err = safe_decode(err)
    output = safe_decode(output)
    if process is not None and process.returncode != 0:
        err = (u._('Command failed. : {error}').format(error=err))
    if print_output:
        LOG.info(output)
    return err, output
Ejemplo n.º 16
0
def handers_action_result(job, status, verbose_level):
    if verbose_level > 2:
        LOG.info('\n\n' + 80 * '=')
        LOG.info(
            u._('DEBUG command output:\n{out}').format(
                out=job.get_console_output()))
    if status == 0:
        if verbose_level > 1:
            # log any ansible warnings
            msg = job.get_error_message()
            if msg:
                LOG.warn(msg)
        LOG.info(u._('Success'))
    else:
        raise CommandError(
            u._('Job failed:\n{msg}').format(msg=job.get_error_message()))
Ejemplo n.º 17
0
    def is_owned_by_me(self):
        """Returns True if we own the lock or False otherwise"""
        try:
            if self.use_flock:
                raise Exception(
                    u._('Invalid use of is_owned_by_me while'
                        'using flock'))

            if not os.path.exists(self.lockpath):
                # lock doesn't exist, just return
                return False
            fd = os.open(self.lockpath, os.O_RDONLY)
            with os.fdopen(fd, 'r') as f:
                contents = f.read(2048).strip().split('\n')
                if len(contents) > 0:
                    self.current_pid = contents[0]
                if len(contents) > 1:
                    self.current_owner = contents[1]

                if contents[0] == str(self.pid):
                    return True
                else:
                    return False
        except Exception as e:
            # it is ok to fail to acquire, we just return that we failed
            LOG.debug('Exception in is_owned_by_me lock check. '
                      'path: %s pid: %s owner: %s error: %s' %
                      (self.lockpath, self.pid, self.owner, str(e)))
        return False
Ejemplo n.º 18
0
    def take_action(self, parsed_args):
        try:
            property_name = parsed_args.propertyname.strip()
            property_value = parsed_args.propertyvalue.strip()
            property_dict = {}
            property_dict[property_name] = property_value

            if parsed_args.hosts:
                if parsed_args.groups:
                    raise CommandError(
                        u._('Invalid to use both hosts and groups arguments '
                            'together.'))

                host_names = _get_names(parsed_args.hosts)

                CLIENT.property_set(property_dict, 'host', host_names)

            elif parsed_args.groups:
                group_names = _get_names(parsed_args.groups)

                CLIENT.property_set(property_dict, 'group', group_names)
            else:
                CLIENT.property_set(property_dict, 'global')

        except Exception:
            raise Exception(traceback.format_exc())
Ejemplo n.º 19
0
    def remove_host(self, hostname, groupname=None):
        """remove host

        if groupname is none, delete host
        if group name is not none, remove host from group
        """
        changed = False
        if groupname and groupname not in self._groups:
            raise NotInInventory(u._('Group'), groupname)

        if hostname not in self._hosts:
            return changed

        changed = True
        host = self._hosts[hostname]
        groups = self.get_groups(host)
        for group in groups:
            if not groupname or groupname == group.name:
                group.remove_host(host)

        host_vars = os.path.join(get_host_vars_dir(), hostname)
        if os.path.exists(host_vars):
            os.remove(host_vars)

        if not groupname:
            del self._hosts[hostname]
        return changed
Ejemplo n.º 20
0
    def take_action(self, parsed_args):
        try:
            data = [('', '')]
            services = CLIENT.service_get_all()
            if services:
                data = []
                for service in services:
                    groupnames = sorted(service.get_groups())
                    data.append((service.name, groupnames))

            data = convert_lists_to_string(data, parsed_args)
            return (u._('Service'), u._('Groups')), sorted(data)
        except ClientException as e:
            raise CommandError(str(e))
        except Exception as e:
            raise Exception(traceback.format_exc())
Ejemplo n.º 21
0
 def get_parser(self, prog_name):
     parser = super(Upgrade, self).get_parser(prog_name)
     parser.add_argument('--services',
                         nargs='?',
                         metavar='<service_list>',
                         help=u._('Upgrade service list'))
     return parser
Ejemplo n.º 22
0
    def _configure_logging(self):
        global LOG
        root_logger = logging.getLogger('')
        root_logger.setLevel(logging.DEBUG)

        handler_found = False
        handlers = root_logger.handlers
        for handler in handlers:
            if isinstance(handler, RotatingFileHandler):
                handler_found = True
                break
        if not handler_found:
            # logger has not been set up
            try:
                rotate_handler = RotatingFileHandler(
                    os.path.join(os.path.abspath(os.sep), 'var', 'log',
                                 'kolla-cli', 'kolla.log'),
                    maxBytes=self._get_kolla_log_file_size(),
                    backupCount=4)

            except IOError as e:
                # most likely the caller is not part of the kolla group
                raise IOError(
                    u._('Permission denied to run the kolla client.'
                        '\nPlease add user to the kolla group and '
                        'then log out and back in. {error}').format(
                            error=str(e)))

            formatter = logging.Formatter(LOG_FILE_MESSAGE_FORMAT)
            rotate_handler.setFormatter(formatter)
            rotate_handler.setLevel(get_log_level())
            root_logger.addHandler(rotate_handler)
            LOG = logging.getLogger(__name__)
Ejemplo n.º 23
0
def get_ansible_command(playbook=False):
    """get a python2 ansible command

    Ansible cannot run yet with python3. If the current default
    python is py3, prefix the ansible command with a py2
    interpreter.
    """
    cmd = 'ansible'
    if playbook:
        cmd = 'ansible-playbook'
    if sys.version_info[0] >= 3:
        # running with py3, find a py2 interpreter for ansible
        py2_path = None
        usr_bin = os.path.join('/', 'usr', 'bin')
        for fname in os.listdir(usr_bin):
            if (fname.startswith('python2.')
                    and os.path.isfile(os.path.join(usr_bin, fname))):
                suffix = fname.split('.')[1]
                if suffix.isdigit():
                    py2_path = os.path.join(usr_bin, fname)
                    break
        if py2_path is None:
            raise Exception(
                u._('ansible-playbook requires python2 and no '
                    'python2 interpreter found in {path}.').format(
                        path=usr_bin))
        cmd = '%s %s' % (py2_path, os.path.join(usr_bin, cmd))
    return cmd
Ejemplo n.º 24
0
    def run(self):
        try:
            locked = self._ansible_lock.wait_acquire()
            if not locked:
                raise Exception(
                    u._('unable to get lock: {lock}, to run '
                        'ansible job: {cmd} ')
                    .format(lock=get_ansible_lock_path(), cmd=self._command))

            LOG.debug('playbook command: %s' % self._command)
            # ansible 2.2 and later introduced an issue where if
            # the playbook is executed from within a directory without
            # read / write permission (which can happen when you,
            # for example, execute via sudo) it will fail.  the
            # workaround will be to run the ansible command from /tmp
            # and then change back to the original directory at the end
            current_dir = os.getcwd()  # nosec
            os.chdir('/tmp')  # nosec
            self._process = subprocess.Popen(self._command,  # nosec
                                             shell=True,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)

            # setup stdout to be read without blocking
            LOG.debug('process pid: %s' % self._process.pid)
            flags = fcntl.fcntl(self._process.stdout, fcntl.F_GETFL)
            fcntl.fcntl(self._process.stdout, fcntl.F_SETFL,
                        (flags | os.O_NONBLOCK))

            # this is also part of the fix for ansible 2.2 and later
            os.chdir(current_dir)
        except Exception as e:
            self._cleanup()
            raise e
Ejemplo n.º 25
0
    def config_import_inventory(self, file_path):
        # type: (str) -> None
        """Config Import Inventory

        Import groups and child associations from the provided
        inventory file. This currently does not import hosts, group
        vars, or host vars that may also exist in the inventory file.

        :param file_path: path to inventory file to import
        :type file_path: string
        """
        check_arg(file_path, u._('File path'), str)
        if not os.path.isfile(file_path):
            raise InvalidArgument(
                u._('File {path} is not valid.').format(path=file_path))
        inventory = Inventory(file_path)
        Inventory.save(inventory)
Ejemplo n.º 26
0
    def set_deploy_mode(self, remote_flag):
        if not remote_flag and len(self._hosts) > 1:
            raise InvalidConfiguration(
                u._('Cannot set local deploy mode when multiple hosts exist.'))
        self.remote_mode = remote_flag

        for group in self.get_groups():
            group.set_remote(remote_flag)
Ejemplo n.º 27
0
 def get_parser(self, prog_name):
     parser = super(PropertyList, self).get_parser(prog_name)
     parser.add_argument('--all',
                         action='store_true',
                         help=u._('List all properties'))
     parser.add_argument('--long',
                         action='store_true',
                         help=u._('Show all property attributes'))
     parser.add_argument('--hosts',
                         nargs=1,
                         metavar='<host_list>',
                         help=u._('Property host list'))
     parser.add_argument('--groups',
                         nargs=1,
                         metavar='<group_list>',
                         help=u._('Property group list'))
     return parser
Ejemplo n.º 28
0
def set_password_sshkey(pwd_key, private_key, public_key):
    cmd = '%s -k %s -r "%s" -u "%s"' % (_get_cmd_prefix(), pwd_key,
                                        private_key, public_key)
    err_msg, output = utils.run_cmd(cmd, print_output=False)
    if err_msg:
        raise FailedOperation(
            u._('Password ssh key set failed. {error} {message}').format(
                error=err_msg, message=output))
Ejemplo n.º 29
0
    def take_action(self, parsed_args):
        try:
            verbose_level = self.app.options.verbose_level
            job = CLIENT.reconfigure(verbose_level)
            status = job.wait()
            if verbose_level > 2:
                LOG.info('\n\n' + 80 * '=')
                LOG.info(u._('DEBUG command output:\n{out}')
                         .format(out=job.get_console_output()))
            if status == 0:
                LOG.info(u._('Success'))
            else:
                raise CommandError(u._('Job failed:\n{msg}')
                                   .format(msg=job.get_error_message()))

        except Exception:
            raise Exception(traceback.format_exc())
Ejemplo n.º 30
0
    def password_set(self, name, value):
        # type: (str, str) -> None
        """Set password

        :param name: name of the password
        :type name: string
        :param value: value of the password
        :type value: string
        """
        check_arg(name, u._('Password name'), str)
        check_arg(value,
                  u._('Password value'),
                  str,
                  display_param=False,
                  empty_ok=True,
                  none_ok=True)
        set_password(name, value)