Esempio n. 1
0
def validate(task):
    """Validates the pre-requisites for iSCSI deploy.

    Validates whether node in the task provided has some ports enrolled.
    This method validates whether conductor url is available either from CONF
    file or from keystone.

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue if the URL of the Ironic API service is not
             configured in config file and is not accessible via Keystone
             catalog.
    :raises: MissingParameterValue if no ports are enrolled for the given node.
    """
    # TODO(lucasagomes): Validate the format of the URL
    deploy_utils.get_ironic_api_url()
    # Validate the root device hints
    try:
        root_device = task.node.properties.get('root_device')
        il_utils.parse_root_device_hints(root_device)
    except ValueError as e:
        raise exception.InvalidParameterValue(
            _('Failed to validate the root device hints for node '
              '%(node)s. Error: %(error)s') % {'node': task.node.uuid,
                                               'error': e})
    deploy_utils.parse_instance_info(task.node)
Esempio n. 2
0
def validate(task):
    """Validates the pre-requisites for iSCSI deploy.

    Validates whether node in the task provided has some ports enrolled.
    This method validates whether conductor url is available either from CONF
    file or from keystone.

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue if the URL of the Ironic API service is not
             configured in config file and is not accessible via Keystone
             catalog.
    :raises: MissingParameterValue if no ports are enrolled for the given node.
    """
    # TODO(lucasagomes): Validate the format of the URL
    deploy_utils.get_ironic_api_url()
    # Validate the root device hints
    try:
        root_device = task.node.properties.get('root_device')
        il_utils.parse_root_device_hints(root_device)
    except ValueError as e:
        raise exception.InvalidParameterValue(
            _('Failed to validate the root device hints for node '
              '%(node)s. Error: %(error)s') % {'node': task.node.uuid,
                                               'error': e})
    deploy_utils.parse_instance_info(task.node)
Esempio n. 3
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        if not task.driver.storage.should_write_image(task):
            # NOTE(TheJulia): There is no reason to validate
            # image properties if we will not be writing an image
            # in a boot from volume case. As such, return to the caller.
            LOG.debug(
                'Skipping complete deployment interface validation '
                'for node %s as it is set to boot from a remote '
                'volume.', node.uuid)
            return

        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(
                    _("image_source's image_checksum must be provided in "
                      "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {
                      'node': node.uuid,
                      'error': e
                  })

        validate_image_proxies(node)
Esempio n. 4
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        if not task.driver.storage.should_write_image(task):
            # NOTE(TheJulia): There is no reason to validate
            # image properties if we will not be writing an image
            # in a boot from volume case. As such, return to the caller.
            LOG.debug('Skipping complete deployment interface validation '
                      'for node %s as it is set to boot from a remote '
                      'volume.', node.uuid)
            return

        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(_(
                    "image_source's image_checksum must be provided in "
                    "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {'node': node.uuid,
                                                   'error': e})

        validate_image_proxies(node)
Esempio n. 5
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node
        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(
                    _("image_source's image_checksum must be provided in "
                      "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {
                      'node': node.uuid,
                      'error': e
                  })

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        validate_image_proxies(node)
Esempio n. 6
0
 def test_parse_root_device_hints_without_operators(self):
     root_device = {
         "wwn": "123456",
         "model": "FOO model",
         "size": 12345,
         "serial": "foo-serial",
         "vendor": "foo VENDOR with space",
         "name": "/dev/sda",
         "wwn_with_extension": "123456111",
         "wwn_vendor_extension": "111",
         "rotational": True,
     }
     result = utils.parse_root_device_hints(root_device)
     expected = {
         "wwn": "s== 123456",
         "model": "s== foo%20model",
         "size": "== 12345",
         "serial": "s== foo-serial",
         "vendor": "s== foo%20vendor%20with%20space",
         "name": "s== /dev/sda",
         "wwn_with_extension": "s== 123456111",
         "wwn_vendor_extension": "s== 111",
         "rotational": True,
     }
     self.assertEqual(expected, result)
Esempio n. 7
0
def _parse_root_device_hints(node):
    """Convert string with hints to dict. """
    root_device = node.properties.get('root_device')
    if not root_device:
        return {}
    try:
        parsed_hints = irlib_utils.parse_root_device_hints(root_device)
    except ValueError as e:
        raise exception.InvalidParameterValue(
            _('Failed to validate the root device hints for node %(node)s. '
              'Error: %(error)s') % {'node': node.uuid, 'error': e})
    root_device_hints = {}
    advanced = {}
    for hint, value in parsed_hints.items():
        if isinstance(value, six.string_types):
            if value.startswith('== '):
                root_device_hints[hint] = int(value[3:])
            elif value.startswith('s== '):
                root_device_hints[hint] = urlparse.unquote(value[4:])
            else:
                advanced[hint] = value
        else:
            root_device_hints[hint] = value
    if advanced:
        raise exception.InvalidParameterValue(
            _('Ansible-deploy does not support advanced root device hints '
              'based on oslo.utils operators. '
              'Present advanced hints for node %(node)s are %(hints)s.') % {
                  'node': node.uuid, 'hints': advanced})
    return root_device_hints
Esempio n. 8
0
def _parse_root_device_hints(node):
    """Convert string with hints to dict. """
    root_device = node.properties.get('root_device')
    if not root_device:
        return {}
    try:
        parsed_hints = irlib_utils.parse_root_device_hints(root_device)
    except ValueError as e:
        raise exception.InvalidParameterValue(
            _('Failed to validate the root device hints for node %(node)s. '
              'Error: %(error)s') % {
                  'node': node.uuid,
                  'error': e
              })
    root_device_hints = {}
    advanced = {}
    for hint, value in parsed_hints.items():
        if isinstance(value, six.string_types):
            if value.startswith('== '):
                root_device_hints[hint] = int(value[3:])
            elif value.startswith('s== '):
                root_device_hints[hint] = urlparse.unquote(value[4:])
            else:
                advanced[hint] = value
        else:
            root_device_hints[hint] = value
    if advanced:
        raise exception.InvalidParameterValue(
            _('Ansible-deploy does not support advanced root device hints '
              'based on oslo.utils operators. '
              'Present advanced hints for node %(node)s are %(hints)s.') % {
                  'node': node.uuid,
                  'hints': advanced
              })
    return root_device_hints
Esempio n. 9
0
def get_root_device_for_deploy(node):
    """Get a root device requested for deployment or None.

    :raises: InvalidParameterValue on invalid hints.
    :return: Parsed root device hints or None if no hints were provided.
    """
    hints = node.instance_info.get('root_device')
    if not hints:
        hints = node.properties.get('root_device')
        if not hints:
            return
        source = 'properties'
    else:
        source = 'instance_info'

    try:
        return il_utils.parse_root_device_hints(hints)
    except ValueError as e:
        raise exception.InvalidParameterValue(
            _('Failed to validate the root device hints %(hints)s (from the '
              'node\'s %(source)s) for node %(node)s. Error: %(error)s') % {
                  'node': node.uuid,
                  'hints': hints,
                  'source': source,
                  'error': e
              })
Esempio n. 10
0
    def test_parse_root_device_hints_with_operators(self):
        root_device = {
            'wwn': 's== 123456',
            'model': 's== foo MODEL',
            'size': '>= 12345',
            'serial': 's!= foo-serial',
            'vendor': 's== foo VENDOR with space',
            'name': '<or> /dev/sda <or> /dev/sdb',
            'wwn_with_extension': 's!= 123456111',
            'wwn_vendor_extension': 's== 111',
            'rotational': True,
            'hctl': 's== 1:0:0:0',
            'by_path': 's== /dev/disk/by-path/1:0:0:0'
        }

        # Validate strings being normalized
        expected = copy.deepcopy(root_device)
        expected['model'] = 's== foo%20model'
        expected['vendor'] = 's== foo%20vendor%20with%20space'
        expected['hctl'] = 's== 1%3A0%3A0%3A0'
        expected['by_path'] = 's== /dev/disk/by-path/1%3A0%3A0%3A0'

        result = utils.parse_root_device_hints(root_device)
        # The hints already contain the operators, make sure we keep it
        self.assertEqual(expected, result)
Esempio n. 11
0
 def test_parse_root_device_hints_without_operators(self):
     root_device = {
         'wwn': '123456',
         'model': 'FOO model',
         'size': 12345,
         'serial': 'foo-serial',
         'vendor': 'foo VENDOR with space',
         'name': '/dev/sda',
         'wwn_with_extension': '123456111',
         'wwn_vendor_extension': '111',
         'rotational': True,
         'hctl': '1:0:0:0',
         'by_path': '/dev/disk/by-path/1:0:0:0'
     }
     result = utils.parse_root_device_hints(root_device)
     expected = {
         'wwn': 's== 123456',
         'model': 's== foo%20model',
         'size': '== 12345',
         'serial': 's== foo-serial',
         'vendor': 's== foo%20vendor%20with%20space',
         'name': 's== /dev/sda',
         'wwn_with_extension': 's== 123456111',
         'wwn_vendor_extension': 's== 111',
         'rotational': True,
         'hctl': 's== 1%3A0%3A0%3A0',
         'by_path': 's== /dev/disk/by-path/1%3A0%3A0%3A0'
     }
     self.assertEqual(expected, result)
Esempio n. 12
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node
        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(_(
                    "image_source's image_checksum must be provided in "
                    "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {'node': node.uuid,
                                                   'error': e})

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        validate_image_proxies(node)
Esempio n. 13
0
    def test_parse_root_device_hints_with_operators(self):
        root_device = {
            "wwn": "s== 123456",
            "model": "s== foo MODEL",
            "size": ">= 12345",
            "serial": "s!= foo-serial",
            "vendor": "s== foo VENDOR with space",
            "name": "<or> /dev/sda <or> /dev/sdb",
            "wwn_with_extension": "s!= 123456111",
            "wwn_vendor_extension": "s== 111",
            "rotational": True,
        }

        # Validate strings being normalized
        expected = copy.deepcopy(root_device)
        expected["model"] = "s== foo%20model"
        expected["vendor"] = "s== foo%20vendor%20with%20space"

        result = utils.parse_root_device_hints(root_device)
        # The hints already contain the operators, make sure we keep it
        self.assertEqual(expected, result)
Esempio n. 14
0
 def test_parse_root_device_hints_convert_size(self):
     for size in (12345, "12345"):
         result = utils.parse_root_device_hints({"size": size})
         self.assertEqual({"size": "== 12345"}, result)
Esempio n. 15
0
 def test_parse_root_device_hints_no_hints(self):
     result = utils.parse_root_device_hints({})
     self.assertIsNone(result)
Esempio n. 16
0
 def test_parse_root_device_hints_convert_size(self):
     for size in (12345, '12345'):
         result = utils.parse_root_device_hints({'size': size})
         self.assertEqual({'size': '== 12345'}, result)
Esempio n. 17
0
 def test_parse_root_device_hints_int_or(self):
     expr = '<or> 123 <or> 456 <or> 789'
     result = utils.parse_root_device_hints({'size': expr})
     self.assertEqual({'size': expr}, result)
Esempio n. 18
0
 def test_parse_root_device_hints_string_or_space(self):
     expr = '<or> foo <or> foo bar <or> bar'
     expected = '<or> foo <or> foo%20bar <or> bar'
     result = utils.parse_root_device_hints({'model': expr})
     self.assertEqual({'model': expected}, result)
Esempio n. 19
0
 def _parse_root_device_hints_convert_rotational(self, values,
                                                 expected_value):
     for value in values:
         result = utils.parse_root_device_hints({'rotational': value})
         self.assertEqual({'rotational': expected_value}, result)
Esempio n. 20
0
 def test_parse_root_device_hints_no_hints(self):
     result = utils.parse_root_device_hints({})
     self.assertIsNone(result)
Esempio n. 21
0
 def _parse_root_device_hints_convert_rotational(self, values, expected_value):
     for value in values:
         result = utils.parse_root_device_hints({"rotational": value})
         self.assertEqual({"rotational": expected_value}, result)
Esempio n. 22
0
 def test_parse_root_device_hints_string_or_space(self):
     expr = "<or> foo <or> foo bar <or> bar"
     expected = "<or> foo <or> foo%20bar <or> bar"
     result = utils.parse_root_device_hints({"model": expr})
     self.assertEqual({"model": expected}, result)
Esempio n. 23
0
 def test_parse_root_device_hints_int_or(self):
     expr = "<or> 123 <or> 456 <or> 789"
     result = utils.parse_root_device_hints({"size": expr})
     self.assertEqual({"size": expr}, result)