Example #1
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:
                    original_value = value
                    value = yaml.safe_load(value)

                    # this check is to make sure that we can assign an empty
                    # string to a property.  without this safe_load will turn
                    # an empty string into a None which is different than an
                    # empty string.
                    if isinstance(original_value, six.string_types)\
                            and value is None:
                        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)
Example #2
0
    def load_container_info(self):
        """get the list of containers on the host"""
        hostname = self.hostname
        err_msg, output = \
            self.inventory.run_ansible_command('-a "docker ps -a"', hostname)
        if err_msg:
            msg = 'Error accessing host %s : %s %s' % (hostname, err_msg,
                                                       output)
            raise FailedOperation(msg)

        if not output:
            msg = ('Host %s is not accessible.' % hostname)
            raise FailedOperation(msg)
        else:
            if '>>' not in output:
                msg = ('Host: %s. Invalid ansible return data: [%s].' %
                       (hostname, output))
                raise FailedOperation(msg)

        if 'NAMES' not in output:
            msg = ('Host: %s. Invalid docker ps return data: [%s].' %
                   (hostname, output))
            raise FailedOperation(msg)

        ansible_properties = AnsibleProperties()
        base_distro = \
            ansible_properties.get_property_value('kolla_base_distro')
        install_type = \
            ansible_properties.get_property_value('kolla_install_type')
        # typically this prefix will be "ol-openstack-"
        container_prefix = base_distro + '-' + install_type + '-'

        # process ps output
        containers = {}

        # the ps output is after the '>>'
        output = output.split('>>', 1)[1]
        LOG.info('docker ps -a on host: %s:\n%s' % (hostname, output))

        lines = output.split('\n')
        for line in lines:
            tokens = line.split()
            if len(tokens) < 2:
                continue
            cid = tokens[0]
            image = tokens[1]
            if container_prefix not in image:
                # skip non-kolla containers
                continue
            name = image.split(container_prefix)[1]
            name = name.split(':')[0]
            containers[cid] = name
        self.container_info = containers
Example #3
0
    def property_clear(self,
                       property_list,
                       property_type=GLOBAL_TYPE,
                       change_set=None):
        # type: (List[str], str, List[str]) -> None
        """Clear a property

        :param property_list: property list
        :type property_list: list
        :param property_type: one of 'global', 'group' or 'host'
        :type property_type: string
        :param change_set: for group or host clears this is the list of
                           groups or hosts to clear the property for
        :type change_set: list of strings

        """
        check_arg(property_list, u._('Property List'), list)
        property_list = safe_decode(property_list)

        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)

        ansible_properties = AnsibleProperties()

        if property_type == GLOBAL_TYPE:
            ansible_properties.clear_property(property_list)
        elif property_type == GROUP_TYPE:
            ansible_properties.clear_group_property(property_list, change_set)
        else:
            ansible_properties.clear_host_property(property_list, change_set)
Example #4
0
    def property_get(self, property_type=GLOBAL_TYPE, get_set=None):
        # type: (str, List[str]) -> List[Property]
        """Returns a list of Property objects

        :param property_type: one of 'global', 'group', or 'host'
        :type property_type: string
        :param get_set: optional list of hosts or groups to be used when
                         getting group or host related property lists
        :type get_set: list of strings
        :return: properties
        :rtype: list of Property objects
        """
        self._check_type(property_type)
        get_set = safe_decode(get_set)

        ansible_properties = AnsibleProperties()

        result_list = []
        if property_type == GLOBAL_TYPE:
            property_list = ansible_properties.get_all_unique()
        elif property_type == GROUP_TYPE:
            property_list = ansible_properties.get_group_list(get_set)
        else:
            property_list = ansible_properties.get_host_list(get_set)

        override_flags = ansible_properties.get_all_override_flags()

        for prop in property_list:
            result = Property(prop, override_flags.get(prop.name, None))
            result_list.append(result)

        return result_list
Example #5
0
    def _run_deploy_rules(self, playbook):
        properties = AnsibleProperties()
        inventory = Inventory.load()

        # cannot have both groups and hosts
        if playbook.hosts and playbook.groups:
            raise InvalidArgument(
                u._('Hosts and Groups arguments cannot '
                    'both be present at the same time.'))

        # verify that all services exists
        if playbook.services:
            for service in playbook.services:
                valid_service = inventory.get_service(service)
                if not valid_service:
                    raise NotInInventory(u._('Service'), service)

        # check that every group with enabled services
        # has hosts associated to it
        group_services = inventory.get_group_services()
        failed_groups = []
        failed_services = []
        if group_services:
            for (groupname, servicenames) in group_services.items():
                group = inventory.get_group(groupname)
                hosts = group.get_hostnames()

                group_needs_host = False
                if not hosts:
                    for servicename in servicenames:
                        if self._is_service_enabled(servicename, inventory,
                                                    properties):
                            group_needs_host = True
                            failed_services.append(servicename)
                    if group_needs_host:
                        failed_groups.append(groupname)

            if len(failed_groups) > 0:
                raise InvalidConfiguration(
                    u._('Deploy failed. '
                        'Groups: {groups} with enabled '
                        'services : {services} '
                        'have no associated hosts').format(
                            groups=failed_groups, services=failed_services))
Example #6
0
def _run_deploy_rules(playbook):
    properties = AnsibleProperties()
    inventory = Inventory.load()

    # check that password file has no empty password values
    empty_keys = get_empty_password_values()
    if empty_keys:
        raise InvalidConfiguration(
            u._('Deploy failed. There are empty password values '
                'in {etc}passwords.yml. '
                'Please run kolla-cli password init or '
                'kolla-cli password set(key) to correct them. '
                '\nEmpty passwords: '
                '{keys}').format(etc=get_kolla_etc(), keys=empty_keys))

    # cannot have both groups and hosts
    if playbook.hosts and playbook.groups:
        raise InvalidArgument(
            u._('Hosts and Groups arguments cannot '
                'both be present at the same time.'))

    # verify that all services exists
    if playbook.services:
        for service in playbook.services:
            valid_service = inventory.get_service(service)
            if not valid_service:
                raise NotInInventory(u._('Service'), service)

    # check that every group with enabled services
    # has hosts associated to it
    group_services = inventory.get_group_services()
    failed_groups = []
    failed_services = []
    if group_services:
        for (groupname, servicenames) in group_services.items():
            group = inventory.get_group(groupname)
            hosts = group.get_hostnames()

            group_needs_host = False
            if not hosts:
                for servicename in servicenames:
                    if _is_service_enabled(servicename, inventory, properties):
                        group_needs_host = True
                        failed_services.append(servicename)
                if group_needs_host:
                    failed_groups.append(groupname)

        if len(failed_groups) > 0:
            raise InvalidConfiguration(
                u._('Deploy failed. '
                    'Groups: {groups} with enabled '
                    'services : {services} '
                    'have no associated hosts').format(
                        groups=failed_groups, services=failed_services))

    # check that ring files are in /etc/kolla/config/swift if
    # swift is enabled
    expected_files = ['account.ring.gz', 'container.ring.gz', 'object.ring.gz']
    is_swift_enabled = _is_service_enabled('swift', inventory, properties)

    if is_swift_enabled:
        path_pre = os.path.join(get_kolla_etc(), 'config', 'swift')
        for expected_file in expected_files:
            path = os.path.join(path_pre, expected_file)
            if not os.path.isfile(path):
                msg = u._('Deploy failed. '
                          'Swift is enabled but ring buffers have '
                          'not yet been set up. Please see the '
                          'documentation for swift configuration '
                          'instructions.')
                raise InvalidConfiguration(msg)