Verified Commit c4f14c96 authored by Marek Veselý's avatar Marek Veselý
Browse files

retrieve data

parent 619eee1b
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ class FileInfoType(DjangoObjectType):
    definition = graphene.Field(ExerciseDefinitionType, required=False)


class OpenSearchDataType(graphene.ObjectType):
    id = graphene.ID(required=True)
    exercise_id = graphene.ID(required=True)
    team_id = graphene.ID(required=True)
    data = graphene.JSONString(required=True)


class ContentType(DjangoObjectType):
    class Meta:
        model = Content
@@ -370,7 +377,9 @@ class TeamType(DjangoObjectType):
    team_questionnaire_states = graphene.List(
        graphene.NonNull(_("TeamQuestionnaireStateInterface")), required=True
    )
    open_search_access = graphene.Field(_("OpenSearchAccessType"), required=False)
    open_search_access = graphene.Field(
        _("OpenSearchAccessType"), required=False
    )

    def resolve_users(self, info):
        access = get_access_for(info.context, self.exercise_id)
+7 −2
Original line number Diff line number Diff line
@@ -213,9 +213,14 @@ def create_exercise(
    create_drive_permissions(teams, definition.files.filter(is_drive=True))

    if exercise.technical:
        from running_exercise.lib.opensearch_client import create_opensearch_exercise, create_opensearch_access
        from running_exercise.lib.opensearch_client import (
            create_opensearch_exercise,
            create_opensearch_access,
        )

        opensearch_credentials = create_opensearch_exercise([team.id for team in teams])
        opensearch_credentials = create_opensearch_exercise(
            [team.id for team in teams]
        )

        print("=== credentials ===")
        print(opensearch_credentials)
+63 −18
Original line number Diff line number Diff line
from typing import List
from opensearchpy import OpenSearch
from datetime import datetime

from common_lib.schema.types import OpenSearchDataType
from exercise.models import OpenSearchAccess

host = "localhost"
@@ -38,12 +40,14 @@ def create_opensearch_exercise(team_ids):
        username = f"team-{team_id}"
        # TODO: Generate a strong password for each user
        password = f"v&ery6#7st*ong78288732-pass889329word-aVUfg9"
        credentials.append({
        credentials.append(
            {
                "team_id": team_id,
                "index_name": index_name,
                "username": username,
                "password": password,
        })
            }
        )
        user_body = {
            "password": password,
        }
@@ -53,21 +57,18 @@ def create_opensearch_exercise(team_ids):
            "cluster_permissions": [
                "cluster:monitor/main",
                "cluster:admin/ingest/pipeline/get",
                "cluster:admin/ingest/pipeline/put"
                "cluster:admin/ingest/pipeline/put",
            ],
            "index_permissions": [
                {
                    "index_patterns": [
                        f"{index_name}"
                    ],
                    "index_patterns": [f"{index_name}"],
                    "allowed_actions": [
                        "indices_all",
                    ]
                    ],
                }
            ]
            ],
        }


        role_mapping_body = {
            "users": [username],
        }
@@ -80,7 +81,9 @@ def create_opensearch_exercise(team_ids):

            # https://docs.opensearch.org/docs/latest/security/access-control/users-roles/#defining-users
            # https://docs.opensearch.org/docs/latest/security/access-control/api/#create-user
            user = client.security.create_user(username=username, body=user_body)
            user = client.security.create_user(
                username=username, body=user_body
            )
            print(f"✓ User")

            # https://docs.opensearch.org/docs/latest/security/access-control/users-roles/#defining-roles
@@ -90,10 +93,13 @@ def create_opensearch_exercise(team_ids):

            # https://docs.opensearch.org/docs/latest/security/access-control/users-roles/#mapping-users-to-roles
            # https://docs.opensearch.org/docs/latest/security/access-control/api/#create-role-mapping
            role_mapping = client.security.create_role_mapping(role=role_name, body=role_mapping_body)
            role_mapping = client.security.create_role_mapping(
                role=role_name, body=role_mapping_body
            )
            print(f"✓ Role mapping")
        except Exception as e:
            print(f"✗ Error")
            print(f"✗ Error {e}")
            # TODO: cleanup and re-raise
            return credentials

    return credentials
@@ -107,8 +113,47 @@ def create_opensearch_access(teams, opensearch_credentials):
                    team=team,
                    index_name=access["index_name"],
                    username=access["username"],
                    password=access["password"]
                    password=access["password"],
                ),
                opensearch_credentials,
            )
        )


def get_exercise_opensearch_data(exercise_id) -> List[OpenSearchDataType]:
    access_list = OpenSearchAccess.objects.filter(team__exercise_id=exercise_id)
    indices = access_list.values_list("index_name", flat=True)

    try:
        # return the last data entries from each index using OpenSearch client
        # https://docs.opensearch.org/docs/latest/api-reference/search-apis/multi-search/

        msearch_body = []
        for index in indices:
            msearch_body.append({"index": index})
            msearch_body.append({"size": 5, "query": {"match_all": {}}})

        msearch_result = client.msearch(
            body=msearch_body,
            index=",".join(indices),
        )
        responses = msearch_result.get("responses", [])
        result = []
        for response in responses:
            if "hits" in response and "hits" in response["hits"]:
                result.append(
                    OpenSearchDataType(
                        id=response["hits"]["hits"][0]["_id"],
                        team_id=access_list.get(
                            index_name=response["hits"]["hits"][0]["_index"]
                        ).team.id,
                        exercise_id=exercise_id,
                        # TODO: process further
                        data=response["hits"]["hits"],
                    )
                )
        print(f"✓ Fetch")
        return result
    except Exception as e:
        print(f"Error {e}")
        raise e
+24 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ from common_lib.schema.enums import LogTypeEnum
from common_lib.schema.types import (
    MilestoneStateType,
    EmailThreadType,
    OpenSearchDataType,
    TeamLearningObjectiveType,
    EmailParticipantType,
    EmailTemplateType,
@@ -233,6 +234,11 @@ class Query(graphene.ObjectType):
        exercise_id=graphene.ID(required=True),
        description="Retrieve all drive files for the given exercise",
    )
    opensearch_data = graphene.List(
        graphene.NonNull(OpenSearchDataType),
        exercise_id=graphene.ID(required=True),
        description="Retrieve some OpenSearch data for the given exercise",
    )

    @protected(User.AuthGroup.TRAINEE)
    def resolve_team(self, info, team_id: str) -> Team:
@@ -568,3 +574,21 @@ class Query(graphene.ObjectType):
        return FileInfo.objects.filter(
            is_drive=True, definition_id=exercise.definition_id
        )

    @protected(User.AuthGroup.INSTRUCTOR)
    def resolve_opensearch_data(
        self, info, exercise_id: str
    ) -> QuerySet[OpenSearchDataType]:
        access = exercise_access(info.context, int(exercise_id))
        if access.group < User.AuthGroup.INSTRUCTOR:
            # TODO: return empty set; OpenSearchDataType is graphene.ObjectType so no .objects is available
            raise PermissionDenied(
                "User does not have access to OpenSearch data for this exercise"
            )

        from running_exercise.lib.opensearch_client import (
            get_exercise_opensearch_data,
        )

        data = get_exercise_opensearch_data(int(exercise_id))
        return data