Ejemplo n.º 1
0
def obj_from_id(resource_config, resources, typename):
    """Return the resource whose name matches the id.

    resource_config has to contain `id`, as it is used to lookup a resource.

    :param resource_config: resource to be transformed
    :param resources: iterable containing all resources
    :param typename: name which describes the type of resource

    :returns: resource object mapped to `id`
    """
    if "id" in resource_config:
        matching = [
            resource for resource in resources
            if resource.id == resource_config["id"]
        ]
        if len(matching) == 1:
            return matching[0]
        elif len(matching) > 1:
            raise exceptions.MultipleMatchesFound(
                needle="{typename} with id '{id}'".format(
                    typename=typename.title(), id=resource_config["id"]),
                haystack=matching)
        else:
            raise exceptions.InvalidScenarioArgument(
                "{typename} with id '{id}' not found".format(
                    typename=typename.title(), id=resource_config["id"]))
    else:
        raise exceptions.InvalidScenarioArgument(
            "{typename} 'id' not found in '{resource_config}'".format(
                typename=typename.title(), resource_config=resource_config))
Ejemplo n.º 2
0
def obj_from_name(resource_config, resources, typename):
    """Return the resource whose name matches the pattern.

    resource_config has to contain `name`, as it is used to lookup a resource.
    Value of the name will be treated as regexp.

    An `InvalidScenarioArgument` is thrown if the pattern does
    not match unambiguously.

    :param resource_config: resource to be transformed
    :param resources: iterable containing all resources
    :param typename: name which describes the type of resource

    :returns: resource object uniquely mapped to `name` or `regex`
    """
    if "name" in resource_config:
        # In a case of pattern string exactly matches resource name
        matching_exact = [
            resource for resource in resources
            if resource.name == resource_config["name"]
        ]
        if len(matching_exact) == 1:
            return matching_exact[0]
        elif len(matching_exact) > 1:
            raise exceptions.InvalidScenarioArgument(
                "{typename} with name '{pattern}' "
                "is ambiguous, possible matches "
                "by id: {ids}".format(typename=typename.title(),
                                      pattern=resource_config["name"],
                                      ids=", ".join(
                                          map(operator.attrgetter("id"),
                                              matching_exact))))
        # Else look up as regex
        patternstr = resource_config["name"]
    elif "regex" in resource_config:
        patternstr = resource_config["regex"]
    else:
        raise exceptions.InvalidScenarioArgument(
            "{typename} 'id', 'name', or 'regex' not found "
            "in '{resource_config}' ".format(typename=typename.title(),
                                             resource_config=resource_config))

    pattern = re.compile(patternstr)
    matching = [
        resource for resource in resources
        if re.search(pattern, resource.name)
    ]
    if not matching:
        raise exceptions.InvalidScenarioArgument(
            "{typename} with pattern '{pattern}' not found".format(
                typename=typename.title(), pattern=pattern.pattern))
    elif len(matching) > 1:
        raise exceptions.InvalidScenarioArgument(
            "{typename} with name '{pattern}' is ambiguous, possible matches "
            "by id: {ids}".format(typename=typename.title(),
                                  pattern=pattern.pattern,
                                  ids=", ".join(
                                      map(operator.attrgetter("id"),
                                          matching))))
    return matching[0]
Ejemplo n.º 3
0
 def _validate_helper(validators, clients, config, task):
     for validator in validators:
         try:
             result = validator(config, clients=clients, task=task)
         except Exception as e:
             raise exceptions.InvalidScenarioArgument(e)
         else:
             if not result.is_valid:
                 raise exceptions.InvalidScenarioArgument(result.msg)
Ejemplo n.º 4
0
 def _validate_helper(validators, clients, config, deployment):
     for validator in validators:
         try:
             result = validator(config, clients=clients,
                                deployment=deployment)
         except Exception as e:
             LOG.exception(e)
             raise exceptions.InvalidScenarioArgument(e)
         else:
             if not result.is_valid:
                 raise exceptions.InvalidScenarioArgument(result.msg)
Ejemplo n.º 5
0
 def pre_process(self, resource_spec, config):
     path = os.path.expanduser(resource_spec)
     if os.path.isfile(path):
         return path
     try:
         head = requests.head(path)
         if head.status_code == 200:
             return path
         raise exceptions.InvalidScenarioArgument(
             "Url %s unavailable (code %s)" % (path, head.status_code))
     except Exception as ex:
         raise exceptions.InvalidScenarioArgument(
             "Url error %s (%s)" % (path, ex))
Ejemplo n.º 6
0
    def test_validator_image_not_in_context(self, mock_glance_image_transform):
        config = {
            "args": {
                "image": "fake_image"
            },
            "context": {
                "images": {
                    "fake_image_name": "foo"
                }
            }
        }

        clients = self.credentials["openstack"]["users"][
            0].get.return_value.clients.return_value
        clients.glance().images.get = mock.Mock()

        result = self.validator.validate(config, self.credentials, None, None)
        self.assertIsNone(result)

        mock_glance_image_transform.assert_called_once_with(
            clients=clients, resource_config=config["args"]["image"])
        clients.glance().images.get.assert_called_with("image_id")

        exs = [exceptions.InvalidScenarioArgument(), glance_exc.HTTPNotFound()]
        for ex in exs:
            clients.glance().images.get.side_effect = ex

            result = self.validator.validate(config, credentials, None, None)

            self.assertEqual("Image 'fake_image' not found", result.msg)
Ejemplo n.º 7
0
    def test__validate_config_semanitc_helper_invalid_arg(self, mock_validate):
        mock_validate.side_effect = exceptions.InvalidScenarioArgument()
        eng = engine.BenchmarkEngine(mock.MagicMock(), mock.MagicMock())

        self.assertRaises(exceptions.InvalidBenchmarkConfig,
                          eng._validate_config_semantic_helper, "a", "u", "n",
                          "p", mock.MagicMock(), {})
Ejemplo n.º 8
0
    def test_validator_image_not_in_context(self, mock_glance_image_transform):
        config = {
            "args": {
                "image": "fake_image"
            },
            "contexts": {
                "images": {
                    "fake_image_name": "foo"
                }
            }
        }

        clients = self.context["users"][0]["credential"].clients.return_value
        clients.glance().images.get = mock.Mock()

        result = self.validator.validate(self.context, config, None, None)
        self.assertIsNone(result)

        mock_glance_image_transform.assert_called_once_with(
            clients=clients, resource_config=config["args"]["image"])
        clients.glance().images.get.assert_called_with("image_id")

        exs = [exceptions.InvalidScenarioArgument(), glance_exc.HTTPNotFound()]
        for ex in exs:
            clients.glance().images.get.side_effect = ex

            e = self.assertRaises(validators.validation.ValidationError,
                                  self.validator.validate, self.context,
                                  config, None, None)

            self.assertEqual("Image 'fake_image' not found", e.message)
Ejemplo n.º 9
0
    def test__get_validated_image_exceptions(self, mock_glance_image):
        mock_glance_image.return_value.pre_process.return_value = "image_id"
        clients = mock.Mock()
        clients.glance().images.get.side_effect = glance_exc.HTTPNotFound("")
        e = self.assertRaises(
            validators.validation.ValidationError,
            self.validator._get_validated_image,
            config, clients, "image")
        self.assertEqual("Image '%s' not found" % config["args"]["image"],
                         e.message)

        mock_glance_image.assert_called_once_with(
            context={"admin": {"credential": clients.credential}})
        mock_glance_image.return_value.pre_process.assert_called_once_with(
            config["args"]["image"], config={})
        clients.glance().images.get.assert_called_with("image_id")
        mock_glance_image.return_value.pre_process.reset_mock()

        clients.side_effect = exceptions.InvalidScenarioArgument("")
        e = self.assertRaises(
            validators.validation.ValidationError,
            self.validator._get_validated_image, config, clients, "image")
        self.assertEqual("Image '%s' not found" % config["args"]["image"],
                         e.message)
        mock_glance_image.return_value.pre_process.assert_called_once_with(
            config["args"]["image"], config={})
        clients.glance().images.get.assert_called_with("image_id")
Ejemplo n.º 10
0
    def test__get_validated_flavor(self, mock_flavor):
        mock_flavor.return_value.pre_process.return_value = "flavor_id"

        clients = mock.Mock()
        clients.nova().flavors.get.return_value = "flavor"

        result = self.validator._get_validated_flavor(self.config,
                                                      clients,
                                                      "flavor")
        self.assertEqual("flavor", result)

        mock_flavor.assert_called_once_with(
            context={"admin": {"credential": clients.credential}}
        )
        mock_flavor_obj = mock_flavor.return_value
        mock_flavor_obj.pre_process.assert_called_once_with(
            self.config["args"]["flavor"], config={})
        clients.nova().flavors.get.assert_called_once_with(flavor="flavor_id")
        mock_flavor_obj.pre_process.reset_mock()

        clients.side_effect = exceptions.InvalidScenarioArgument("")
        result = self.validator._get_validated_flavor(
            self.config, clients, "flavor")
        self.assertEqual("flavor", result)
        mock_flavor_obj.pre_process.assert_called_once_with(
            self.config["args"]["flavor"], config={})
        clients.nova().flavors.get.assert_called_with(flavor="flavor_id")
Ejemplo n.º 11
0
    def test__get_validated_image_exceptions(self,
                                             mock_glance_image_transform):
        clients = mock.Mock()
        clients.glance().images.get.return_value = "image"
        clients.glance().images.get.side_effect = glance_exc.HTTPNotFound("")
        result = self.validator._get_validated_image(config, clients, "image")
        self.assertIsInstance(result[0], validators.ValidationResult)
        self.assertFalse(result[0].is_valid)
        self.assertEqual(result[0].msg,
                         "Image '%s' not found" % config["args"]["image"])
        self.assertIsNone(result[1])
        mock_glance_image_transform.assert_called_once_with(
            clients=clients, resource_config=config["args"]["image"])
        clients.glance().images.get.assert_called_with("image_id")

        clients.side_effect = exceptions.InvalidScenarioArgument("")
        result = self.validator._get_validated_image(config, clients, "image")
        self.assertIsInstance(result[0], validators.ValidationResult)
        self.assertFalse(result[0].is_valid)
        self.assertEqual(result[0].msg,
                         "Image '%s' not found" % config["args"]["image"])
        self.assertIsNone(result[1])
        mock_glance_image_transform.assert_called_with(
            clients=clients, resource_config=config["args"]["image"])
        clients.glance().images.get.assert_called_with("image_id")
Ejemplo n.º 12
0
    def _get_flavor_from_context(self, config, flavor_value):
        if "flavors" not in config.get("context", {}):
            raise exceptions.InvalidScenarioArgument("No flavors context")

        flavors = [flavors_ctx.FlavorConfig(**f)
                   for f in config["context"]["flavors"]]
        resource = types.obj_from_name(resource_config=flavor_value,
                                       resources=flavors, typename="flavor")
        flavor = flavors_ctx.FlavorConfig(**resource)
        flavor.id = "<context flavor: %s>" % flavor.name
        return (ValidationResult(True), flavor)
Ejemplo n.º 13
0
 def validate_semantic(cls, config, admin, users, task):
     """Check if the image service is available."""
     try:
         glance = users[0].glance()
         list(glance.images.list(limit=0))
     except Exception as e:
         message = _(
             "The image service is unavailable, Reason: %(reason)s") % {
                 "reason": six.text_type(e)
             }
         raise exceptions.InvalidScenarioArgument(message=message)
Ejemplo n.º 14
0
def _id_from_name(resource_config, resources, typename):
    """Return the id of the resource whose name matches the pattern.

    When resource_config contains `name`, an exact match is used.
    When resource_config contains `regex`, a pattern match is used.

    An `InvalidScenarioArgument` is thrown if the pattern does
    not match unambiguously.

    :param resource_config: resource to be transformed
    :param resources: iterable containing all resources
    :param typename: name which describes the type of resource

    :returns: resource id uniquely mapped to `name` or `regex`
    """
    if resource_config.get('name'):
        patternstr = "^{0}$".format(resource_config.get('name'))
    elif resource_config.get('regex'):
        patternstr = resource_config.get('regex')
    else:
        raise exceptions.InvalidScenarioArgument(
            "{typename} 'id', 'name', or 'regex' not found "
            "in '{resource_config}' ".format(typename=typename.title(),
                                             resource_config=resource_config))

    pattern = re.compile(patternstr)
    matching = filter(lambda resource: re.search(pattern, resource.name),
                      resources)
    if not matching:
        raise exceptions.InvalidScenarioArgument(
            "{typename} with pattern '{pattern}' not found".format(
                typename=typename.title(), pattern=pattern.pattern))
    elif len(matching) > 1:
        raise exceptions.InvalidScenarioArgument(
            "{typename} with name '{pattern}' is ambiguous, possible matches "
            "by id: {ids}".format(typename=typename.title(),
                                  pattern=pattern.pattern,
                                  ids=", ".join(
                                      map(operator.attrgetter("id"),
                                          matching))))
    return matching[0].id
Ejemplo n.º 15
0
    def transform(cls, clients, resource_config):
        """Check whether file exists or url available.

        :param clients: openstack admin client handles
        :param resource_config: path or url

        :returns: url or expanded file path
        """

        path = os.path.expanduser(resource_config)
        if os.path.isfile(path):
            return path
        try:
            head = requests.head(path)
            if head.status_code == 200:
                return path
            raise exceptions.InvalidScenarioArgument(
                "Url %s unavailable (code %s)" % (path, head.status_code))
        except Exception as ex:
            raise exceptions.InvalidScenarioArgument("Url error %s (%s)" %
                                                     (path, ex))
Ejemplo n.º 16
0
    def pre_process(self, resource_spec, config):
        resource_id = resource_spec.get("id")
        if resource_id:
            return resource_id
        else:
            neutronclient = self._clients.neutron()
            for net in neutronclient.list_networks()["networks"]:
                if net["name"] == resource_spec.get("name"):
                    return net["id"]

        raise exceptions.InvalidScenarioArgument(
            "Neutron network with name '{name}' not found".format(
                name=resource_spec.get("name")))
Ejemplo n.º 17
0
    def transform(cls, clients, resource_config):
        """Transform the resource config to id.

        :param clients: openstack admin client handles
        :param resource_config: scenario config with `id`, `name` or `regex`

        :returns: id matching resource
        """
        resource_id = resource_config.get("id")
        if resource_id:
            return resource_id
        else:
            neutronclient = clients.neutron()
            for net in neutronclient.list_networks()["networks"]:
                if net["name"] == resource_config.get("name"):
                    return net["id"]

        raise exceptions.InvalidScenarioArgument(
            "Neutron network with name '{name}' not found".format(
                name=resource_config.get("name")))
Ejemplo n.º 18
0
    def test__get_validated_flavor(self, mock_flavor_transform):

        clients = mock.Mock()
        clients.nova().flavors.get.return_value = "flavor"

        result = self.validator._get_validated_flavor(self.config, clients,
                                                      "flavor")
        self.assertEqual("flavor", result)

        mock_flavor_transform.assert_called_once_with(
            clients=clients, resource_config=self.config["args"]["flavor"])
        clients.nova().flavors.get.assert_called_once_with(flavor="flavor_id")

        clients.side_effect = exceptions.InvalidScenarioArgument("")
        result = self.validator._get_validated_flavor(self.config, clients,
                                                      "flavor")
        self.assertEqual("flavor", result)
        mock_flavor_transform.assert_called_with(
            clients=clients, resource_config=self.config["args"]["flavor"])
        clients.nova().flavors.get.assert_called_with(flavor="flavor_id")
Ejemplo n.º 19
0
    def test__get_validated_image_exceptions(self,
                                             mock_glance_image_transform):
        clients = mock.Mock()
        clients.glance().images.get.return_value = "image"
        clients.glance().images.get.side_effect = glance_exc.HTTPNotFound("")
        e = self.assertRaises(validators.validation.ValidationError,
                              self.validator._get_validated_image, config,
                              clients, "image")
        self.assertEqual("Image '%s' not found" % config["args"]["image"],
                         e.message)
        mock_glance_image_transform.assert_called_once_with(
            clients=clients, resource_config=config["args"]["image"])
        clients.glance().images.get.assert_called_with("image_id")

        clients.side_effect = exceptions.InvalidScenarioArgument("")
        e = self.assertRaises(validators.validation.ValidationError,
                              self.validator._get_validated_image, config,
                              clients, "image")
        self.assertEqual("Image '%s' not found" % config["args"]["image"],
                         e.message)
        mock_glance_image_transform.assert_called_with(
            clients=clients, resource_config=config["args"]["image"])
        clients.glance().images.get.assert_called_with("image_id")
Ejemplo n.º 20
0
    def _find_resource(self, resource_spec, resources):
        """Return the resource whose name matches the pattern.

        .. note:: This method is a modified version of
            `rally.task.types.obj_from_name`. The difference is supporting the
            case of returning the latest version of resource in case of
            `accurate=False` option.

        :param resource_spec: resource specification to find.
            Expected keys:

            * name - The exact name of resource to search. If no exact match
              and value of *accurate* key is False (default behaviour), name
              will be interpreted as a regexp
            * regexp - a regexp of resource name to match. If several resources
              match and value of *accurate* key is False (default behaviour),
              the latest resource will be returned.
        :param resources: iterable containing all resources
        :raises InvalidScenarioArgument: if the pattern does
            not match anything.

        :returns: resource object mapped to `name` or `regex`
        """
        if "name" in resource_spec:
            # In a case of pattern string exactly matches resource name
            matching_exact = [
                resource for resource in resources
                if resource.name == resource_spec["name"]
            ]
            if len(matching_exact) == 1:
                return matching_exact[0]
            elif len(matching_exact) > 1:
                raise exceptions.InvalidScenarioArgument(
                    "%(typename)s with name '%(pattern)s' "
                    "is ambiguous, possible matches "
                    "by id: %(ids)s" % {
                        "typename":
                        self.get_name().title(),
                        "pattern":
                        resource_spec["name"],
                        "ids":
                        ", ".join(
                            map(operator.attrgetter("id"), matching_exact))
                    })
            if resource_spec.get("accurate", False):
                raise exceptions.InvalidScenarioArgument(
                    "%(typename)s with name '%(name)s' not found" % {
                        "typename": self.get_name().title(),
                        "name": resource_spec["name"]
                    })
            # Else look up as regex
            patternstr = resource_spec["name"]
        elif "regex" in resource_spec:
            patternstr = resource_spec["regex"]
        else:
            raise exceptions.InvalidScenarioArgument(
                "%(typename)s 'id', 'name', or 'regex' not found "
                "in '%(resource_spec)s' " % {
                    "typename": self.get_name().title(),
                    "resource_spec": resource_spec
                })

        pattern = re.compile(patternstr)
        matching = [
            resource for resource in resources
            if re.search(pattern, resource.name or "")
        ]
        if not matching:
            raise exceptions.InvalidScenarioArgument(
                "%(typename)s with pattern '%(pattern)s' not found" % {
                    "typename": self.get_name().title(),
                    "pattern": pattern.pattern
                })
        elif len(matching) > 1:
            if not resource_spec.get("accurate", False):
                return sorted(matching, key=lambda o: o.name or "")[-1]

            raise exceptions.InvalidScenarioArgument(
                "%(typename)s with name '%(pattern)s' is ambiguous, possible "
                "matches by id: %(ids)s" % {
                    "typename": self.get_name().title(),
                    "pattern": pattern.pattern,
                    "ids": ", ".join(map(operator.attrgetter("id"), matching))
                })
        return matching[0]
Ejemplo n.º 21
0
 def _validate_helper(validators, clients, args, task):
     for validator in validators:
         result = validator(clients=clients, task=task, **args)
         if not result.is_valid:
             raise exceptions.InvalidScenarioArgument(message=result.msg)