예제 #1
0
    def _check_config_from_context(cls, config_context, team_id):
        # To avoid multiple identical calls to the database
        already_checked_rules = set()

        for label_name, meta in config_context["all_labels"].items():
            # This is not possible to schedule an operation or a rule after an aggregation
            # The only task authorized after an aggregation is also another aggregation
            try:
                dstream_label_name, dstream_compute_type = config_context[
                    "labels_with_downstream"
                ][label_name]
                if (
                    config_context["all_labels"][label_name]["compute_type"]
                    == "aggregation"
                    and dstream_compute_type != "aggregation"
                ):
                    raise IntegrityError(
                        'Label "{dstream_label_name}" could not be executed after label "{label_name}"'.format(
                            dstream_label_name=dstream_label_name, label_name=label_name
                        )
                    )
            except KeyError:
                # It happens when the current label has no downstream compute task
                # (not present into config_context['labels_with_downstream'])
                pass

            if (
                meta["compute_type"] == "rule"
                and config_context["all_labels"][label_name]["rule_name"]
                not in already_checked_rules
            ):
                # Search if the rule exists
                rule_name = config_context["all_labels"][label_name]["rule_name"]

                try:
                    RuleController.get(
                        filters={"Rule": {"name": rule_name, "team_id": team_id}}
                    )
                except NotFoundError:
                    raise NotFoundError(
                        'Rule "{rule}" defined in label "{label}" does not exist'.format(
                            rule=rule_name, label=label_name
                        )
                    )
                already_checked_rules.add(rule_name)
            # This is an operation or an aggregation
            elif (
                meta["compute_type"] == "operation"
                or meta["compute_type"] == "aggregation"
            ):
                for dep in meta["dependencies"]:
                    if dep not in config_context["all_labels"].keys():
                        msg = (
                            'Dependency "{dep}" declared in label "{label}" has not '
                            "been declared in the configuration"
                        )
                        raise NotFoundError(msg.format(dep=dep, label=label_name))
예제 #2
0
def execute_rule(team_id, rule_id):
    """

    .. :quickref: POST; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    payload = get_payload()

    # Does the team owns the rule
    RuleController.get({"Rule": {"id": rule_id, "team_id": team_id}})

    result = RuleController.execute(rule_id, **payload)
    return jsonify({"result": result}), 200
예제 #3
0
파일: checks.py 프로젝트: mferon/depc
def list_rule_checks(team_id, rule_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    rule = RuleController.get(
        filters={"Rule": {
            "id": rule_id,
            "team_id": team_id
        }})
    return jsonify({"checks": [format_check(r) for r in rule["checks"]]}), 200
예제 #4
0
파일: rules.py 프로젝트: dingcycle/depc
def get_rule(team_id, rule_id):
    """Return a specific rule.

    .. :quickref: GET; Return a specific rule.

    **Example request**:

    .. sourcecode:: http

      GET /teams/66859c4a-3e0a-4968-a5a4-4c3b8662acb7/rules/ff130e9b-d226-4465-9612-a93e12799091 HTTP/1.1
      Host: example.com
      Accept: application/json

    **Example response**:

    .. sourcecode:: http

      HTTP/1.1 200 OK

      {
        "checks": [],
        "createdAt": "2018-05-17T12:01:09Z",
        "description": "Compute the QOS of our servers",
        "id": "ff130e9b-d226-4465-9612-a93e12799091",
        "name": "Servers",
        "updatedAt": "2018-11-09T15:33:06Z"
      }

    :resheader Content-Type: application/json
    :status 200: the rule
    """
    if not TeamPermission.is_user(team_id):
        abort(403)

    rule = RuleController.get(
        filters={"Rule": {
            "id": rule_id,
            "team_id": team_id
        }})
    return jsonify(format_rule(rule)), 200
예제 #5
0
    def execute(self, context):
        from depc.controllers import NotFoundError
        from depc.controllers.rules import RuleController
        from depc.extensions import redis_scheduler as redis
        from depc.utils import get_start_end_ts

        ds = context["ds"]
        start, end = get_start_end_ts(ds)

        with self.app.app_context():

            # Get the nodes for this team and this label
            query = ("MATCH(n:{label}) RETURN n AS Node "
                     "ORDER BY Node.name "
                     "SKIP {skip} LIMIT {limit}")
            query = query.format(label=self.full_label,
                                 skip=self.skip,
                                 limit=int(self.length))

            records = get_records(query)
            nodes = [dict(record.get("Node").items()) for record in records]

            # Remove old nodes
            nodes = [n for n in nodes if is_active_node(start, end, n)]

            # Get the rule associated to the label for this team
            try:
                rule = RuleController.get(filters={
                    "Rule": {
                        "name": self.rule_name,
                        "team_id": self.team_id
                    }
                })
            except NotFoundError:
                self.log.warning(
                    "[{0}] The label {1} has no associated rule in DEPC".
                    format(self.team_name, self.label))
                return False

            has_qos = False
            auto_fill = check_enable_auto_fill(rule["id"], self.team_id)
            for node in nodes:
                result = RuleController.execute(
                    rule_id=rule["id"],
                    auto_fill=auto_fill,
                    name=node["name"],
                    start=start,
                    end=end,
                )

                if result["qos"]["qos"] != "unknown":
                    has_qos = True
                    self.log.info("[{0}/{1}] The QOS of {2} is {3}%".format(
                        self.team_name,
                        self.label,
                        node["name"],
                        result["qos"]["qos"],
                    ))

                    # Saving to Beamium
                    self.write_metric(
                        metric="depc.qos.node",
                        ts=start,
                        value=result["qos"]["qos"],
                        tags={
                            "label": self.label,
                            "name": node["name"],
                            "team": self.team_id,
                        },
                    )

                    # Used for average computing
                    key = "{ds}.{team}.{label}".format(ds=ds,
                                                       team=self.team_name,
                                                       label=self.label)

                    if not self.excluded_from_label_average(
                            self.team_name, self.label, node["name"]):
                        redis.zadd("{}.sorted".format(key), node["name"],
                                   result["qos"]["qos"])

                    # Save information to reuse it later (`bools_dps` is used in
                    # OperationOperator and `qos` is used in AggregationOperator)
                    redis.set(
                        "{}.{}.node".format(key, node["name"]),
                        json.dumps({
                            "bools_dps": result["qos"]["bools_dps"],
                            "qos": result["qos"]["qos"],
                        }),
                    )

                else:
                    self.log.warning("[{0}/{1}] No QOS for {2}".format(
                        self.team_name, self.label, node["name"]))

                    # Add it in redis to compute some stats in AfterSubdagOperator
                    redis.sadd(
                        "{ds}.{team}.{label}.noqos".format(ds=ds,
                                                           team=self.team_name,
                                                           label=self.label),
                        node["name"],
                    )

            if not has_qos:
                self.log.warning("[{0}/{1}] No QOS found for any items".format(
                    self.team_name, self.label))