Exemplo n.º 1
0
def commit_config(task):
    """Commits pending changes added by set_config

    :param task: is the ironic task for running the config job.
    :raises: DracClientError on an error from pywsman library.
    :raises: DracPendingConfigJobExists if the job is already created.
    :raises: DracOperationFailed if the client received response with an
             error message.
    :raises: DracUnexpectedReturnValue if the client received a response
             with unexpected return value

    """
    node = task.node
    management.check_for_config_job(node)
    management.create_config_job(node)
Exemplo n.º 2
0
def commit_config(task):
    """Commits pending changes added by set_config

    :param task: is the ironic task for running the config job.
    :raises: DracClientError on an error from pywsman library.
    :raises: DracPendingConfigJobExists if the job is already created.
    :raises: DracOperationFailed if the client received response with an
             error message.
    :raises: DracUnexpectedReturnValue if the client received a response
             with unexpected return value

    """
    node = task.node
    management.check_for_config_job(node)
    management.create_config_job(node)
Exemplo n.º 3
0
    def test__check_for_config_job_not_exist(self, mock_client_pywsman):
        job_statuses = ["Completed", "Completed with Errors", "Failed"]
        for job_status in job_statuses:
            result_xml = test_utils.build_soap_xml(
                [{'DCIM_LifecycleJob': {'Name': 'BIOS.Setup.1-1',
                                        'JobStatus': job_status,
                                        'InstanceID': 'fake'}}],
                resource_uris.DCIM_LifecycleJob)

            mock_xml = test_utils.mock_wsman_root(result_xml)
            mock_pywsman = mock_client_pywsman.Client.return_value
            mock_pywsman.enumerate.return_value = mock_xml

            try:
                drac_mgmt.check_for_config_job(self.node)
            except (exception.DracClientError,
                    exception.DracPendingConfigJobExists):
                self.fail("Failed to detect completed job due to "
                          "\"{}\" job status".format(job_status))
Exemplo n.º 4
0
    def test__check_for_config_job_not_exist(self, mock_client_pywsman):
        job_statuses = ["Completed", "Completed with Errors", "Failed"]
        for job_status in job_statuses:
            result_xml = test_utils.build_soap_xml(
                [{'DCIM_LifecycleJob': {'Name': 'BIOS.Setup.1-1',
                                        'JobStatus': job_status,
                                        'InstanceID': 'fake'}}],
                resource_uris.DCIM_LifecycleJob)

            mock_xml = test_utils.mock_wsman_root(result_xml)
            mock_pywsman = mock_client_pywsman.Client.return_value
            mock_pywsman.enumerate.return_value = mock_xml

            try:
                drac_mgmt.check_for_config_job(self.node)
            except (exception.DracClientError,
                    exception.DracPendingConfigJobExists):
                self.fail("Failed to detect completed job due to "
                          "\"{}\" job status".format(job_status))
Exemplo n.º 5
0
    def test__check_for_config_job(self, mock_client_pywsman):
        result_xml = test_utils.build_soap_xml(
            [{'DCIM_LifecycleJob': {'Name': 'fake'}}],
            resource_uris.DCIM_LifecycleJob)

        mock_xml = test_utils.mock_wsman_root(result_xml)
        mock_pywsman = mock_client_pywsman.Client.return_value
        mock_pywsman.enumerate.return_value = mock_xml

        result = drac_mgmt.check_for_config_job(self.node)

        self.assertIsNone(result)
        mock_pywsman.enumerate.assert_called_once_with(
            mock.ANY, mock.ANY, resource_uris.DCIM_LifecycleJob)
Exemplo n.º 6
0
    def test__check_for_config_job(self, mock_client_pywsman):
        result_xml = test_utils.build_soap_xml(
            [{'DCIM_LifecycleJob': {'Name': 'fake'}}],
            resource_uris.DCIM_LifecycleJob)

        mock_xml = test_utils.mock_wsman_root(result_xml)
        mock_pywsman = mock_client_pywsman.Client.return_value
        mock_pywsman.enumerate.return_value = mock_xml

        result = drac_mgmt.check_for_config_job(self.node)

        self.assertIsNone(result)
        mock_pywsman.enumerate.assert_called_once_with(
            mock.ANY, mock.ANY, resource_uris.DCIM_LifecycleJob)
Exemplo n.º 7
0
def set_config(task, **kwargs):
    """Sets the pending_value parameter for each of the values passed in.

    :param task: an ironic task object.
    :param kwargs: a dictionary of {'AttributeName': 'NewValue'}
    :raises: DracOperationFailed if any new values are invalid.
    :raises: DracOperationFailed if any of the attributes are read-only.
    :raises: DracOperationFailed if any of the attributes cannot be set for
             any other reason.
    :raises: DracClientError on an error from the pywsman library.
    :returns: A boolean indicating whether commit_config needs to be
              called to make the changes.

    """
    node = task.node
    management.check_for_config_job(node)
    current = get_config(node)
    unknown_keys = set(kwargs) - set(current)
    if unknown_keys:
        LOG.warning(_LW('Ignoring unknown BIOS attributes "%r"'), unknown_keys)

    candidates = set(kwargs) - unknown_keys
    read_only_keys = []
    unchanged_attribs = []
    invalid_attribs_msgs = []
    attrib_names = []

    for k in candidates:
        if str(kwargs[k]) == str(current[k]['current_value']):
            unchanged_attribs.append(k)
        elif current[k]['read_only']:
            read_only_keys.append(k)
        else:
            if 'possible_values' in current[k]:
                if str(kwargs[k]) not in current[k]['possible_values']:
                    m = _('Attribute %(attr)s cannot be set to value %(val)s.'
                          ' It must be in %(ok)r') % {
                              'attr': k,
                              'val': kwargs[k],
                              'ok': current[k]['possible_values']
                          }
                    invalid_attribs_msgs.append(m)
                    continue
            if ('pcre_regex' in current[k]
                    and current[k]['pcre_regex'] is not None):
                regex = re.compile(current[k]['pcre_regex'])
                if regex.search(str(kwargs[k])) is None:
                    # TODO(victor-lowther)
                    # Leave untranslated for now until the unicode
                    # issues that the test suite exposes are straightened out.
                    m = ('Attribute %(attr)s cannot be set to value %(val)s.'
                         ' It must match regex %(re)s.') % {
                             'attr': k,
                             'val': kwargs[k],
                             're': current[k]['pcre_regex']
                         }
                    invalid_attribs_msgs.append(m)
                    continue
            if 'lower_bound' in current[k]:
                lower = current[k]['lower_bound']
                upper = current[k]['upper_bound']
                val = int(kwargs[k])
                if val < lower or val > upper:
                    m = _('Attribute %(attr)s cannot be set to value %(val)d.'
                          ' It must be between %(lower)d and %(upper)d.') % {
                              'attr': k,
                              'val': val,
                              'lower': lower,
                              'upper': upper
                          }
                    invalid_attribs_msgs.append(m)
                    continue
            attrib_names.append(k)

    if unchanged_attribs:
        LOG.warning(_LW('Ignoring unchanged BIOS settings %r'),
                    unchanged_attribs)

    if invalid_attribs_msgs or read_only_keys:
        raise exception.DracOperationFailed(
            _format_error_msg(invalid_attribs_msgs, read_only_keys))

    if not attrib_names:
        return False

    client = wsman_client.get_wsman_client(node)
    selectors = {
        'CreationClassName': 'DCIM_BIOSService',
        'Name': 'DCIM:BIOSService',
        'SystemCreationClassName': 'DCIM_ComputerSystem',
        'SystemName': 'DCIM:ComputerSystem'
    }
    properties = {
        'Target': 'BIOS.Setup.1-1',
        'AttributeName': attrib_names,
        'AttributeValue': map(lambda k: kwargs[k], attrib_names)
    }
    doc = client.wsman_invoke(resource_uris.DCIM_BIOSService, 'SetAttributes',
                              selectors, properties)
    # Yes, we look for RebootRequired.  In this context, that actually means
    # that we need to create a lifecycle controller config job and then reboot
    # so that the lifecycle controller can commit the BIOS config changes that
    # we have proposed.
    set_results = doc.findall('.//{%s}RebootRequired' %
                              resource_uris.DCIM_BIOSService)
    return any(str(res.text) == 'Yes' for res in set_results)
Exemplo n.º 8
0
def set_config(task, **kwargs):
    """Sets the pending_value parameter for each of the values passed in.

    :param task: an ironic task object.
    :param kwargs: a dictionary of {'AttributeName': 'NewValue'}
    :raises: DracOperationFailed if any new values are invalid.
    :raises: DracOperationFailed if any of the attributes are read-only.
    :raises: DracOperationFailed if any of the attributes cannot be set for
             any other reason.
    :raises: DracClientError on an error from the pywsman library.
    :returns: A boolean indicating whether commit_config needs to be
              called to make the changes.

    """
    node = task.node
    management.check_for_config_job(node)
    current = get_config(node)
    unknown_keys = set(kwargs) - set(current)
    if unknown_keys:
        LOG.warning(_LW('Ignoring unknown BIOS attributes "%r"'),
                    unknown_keys)

    candidates = set(kwargs) - unknown_keys
    read_only_keys = []
    unchanged_attribs = []
    invalid_attribs_msgs = []
    attrib_names = []

    for k in candidates:
        if str(kwargs[k]) == str(current[k]['current_value']):
            unchanged_attribs.append(k)
        elif current[k]['read_only']:
            read_only_keys.append(k)
        else:
            if 'possible_values' in current[k]:
                if str(kwargs[k]) not in current[k]['possible_values']:
                    m = _('Attribute %(attr)s cannot be set to value %(val)s.'
                          ' It must be in %(ok)r') % {
                              'attr': k,
                              'val': kwargs[k],
                              'ok': current[k]['possible_values']}
                    invalid_attribs_msgs.append(m)
                    continue
            if ('pcre_regex' in current[k] and
                current[k]['pcre_regex'] is not None):
                regex = re.compile(current[k]['pcre_regex'])
                if regex.search(str(kwargs[k])) is None:
                    # TODO(victor-lowther)
                    # Leave untranslated for now until the unicode
                    # issues that the test suite exposes are straightened out.
                    m = ('Attribute %(attr)s cannot be set to value %(val)s.'
                         ' It must match regex %(re)s.') % {
                             'attr': k,
                             'val': kwargs[k],
                             're': current[k]['pcre_regex']}
                    invalid_attribs_msgs.append(m)
                    continue
            if 'lower_bound' in current[k]:
                lower = current[k]['lower_bound']
                upper = current[k]['upper_bound']
                val = int(kwargs[k])
                if val < lower or val > upper:
                    m = _('Attribute %(attr)s cannot be set to value %(val)d.'
                          ' It must be between %(lower)d and %(upper)d.') % {
                              'attr': k,
                              'val': val,
                              'lower': lower,
                              'upper': upper}
                    invalid_attribs_msgs.append(m)
                    continue
            attrib_names.append(k)

    if unchanged_attribs:
        LOG.warning(_LW('Ignoring unchanged BIOS settings %r'),
                    unchanged_attribs)

    if invalid_attribs_msgs or read_only_keys:
        raise exception.DracOperationFailed(
            _format_error_msg(invalid_attribs_msgs, read_only_keys))

    if not attrib_names:
        return False

    client = wsman_client.get_wsman_client(node)
    selectors = {'CreationClassName': 'DCIM_BIOSService',
                 'Name': 'DCIM:BIOSService',
                 'SystemCreationClassName': 'DCIM_ComputerSystem',
                 'SystemName': 'DCIM:ComputerSystem'}
    properties = {'Target': 'BIOS.Setup.1-1',
                  'AttributeName': attrib_names,
                  'AttributeValue': map(lambda k: kwargs[k], attrib_names)}
    doc = client.wsman_invoke(resource_uris.DCIM_BIOSService,
                              'SetAttributes',
                              selectors,
                              properties)
    # Yes, we look for RebootRequired.  In this context, that actually means
    # that we need to create a lifecycle controller config job and then reboot
    # so that the lifecycle controller can commit the BIOS config changes that
    # we have proposed.
    set_results = doc.findall(
        './/{%s}RebootRequired' % resource_uris.DCIM_BIOSService)
    return any(str(res.text) == 'Yes' for res in set_results)