# If anyone changes or improve the following tests for Model Registry, please
# consider reflecting the same changes on https://github.com/kubeflow/model-registry
name: Test Model Registry
on:
  pull_request:
    paths:
    - tests/install_KinD_create_KinD_cluster_install_kustomize.sh
    - .github/workflows/model_registry_test.yaml
    - applications/model-registry/upstream/**
    - tests/istio*
    - common/istio*/**

permissions:
  contents: read
  actions: read

jobs:
  build-kfmr:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v4

    - name: Install KinD, Create KinD cluster and Install kustomize
      run: ./tests/install_KinD_create_KinD_cluster_install_kustomize.sh

    - name: Remove AppArmor profile for mysql in KinD on GHA # https://github.com/kubeflow/manifests/issues/2507
      run: |
        set -x
        sudo apt-get install apparmor-profiles
        sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

    - name: Install kubectl
      run: ./tests/kubectl_install.sh

    - name: Create kubeflow namespace
      run: kustomize build common/kubeflow-namespace/base | kubectl apply -f -

    - name: Install Istio
      run: ./tests/istio-cni_install.sh

    - name: Install oauth2-proxy
      run: ./tests/oauth2-proxy_install.sh

    - name: Install cert-manager
      run: ./tests/cert_manager_install.sh

    - name: Install KF Multi Tenancy
      run: ./tests/multi_tenancy_install.sh

    - name: Install kubeflow-istio-resources
      run: kustomize build common/istio/kubeflow-istio-resources/base | kubectl apply -f -

    - name: Create KF Profile
      run: kustomize build common/user-namespace/base | kubectl apply -f -

    - name: Build & Apply KF Model Registry manifests
      run: |
        kustomize build applications/model-registry/upstream/overlays/db | kubectl apply -n kubeflow -f -
        kustomize build applications/model-registry/upstream/options/istio | kubectl apply -n kubeflow -f -

    - name: Build & Apply KF Model Registry UI manifests
      run: |
        kustomize build applications/model-registry/upstream/options/ui/overlays/istio | kubectl apply -n kubeflow -f -

    - name: Test KF Model Registry deployment
      run: |
        echo "Waiting for all Model Registry Pods to become ready..."
        if ! kubectl wait --for=condition=available -n kubeflow deployment/model-registry-db --timeout=600s ; then
            kubectl events -A
            kubectl describe deployment/model-registry-db -n kubeflow
            kubectl logs deployment/model-registry-db -n kubeflow
            exit 1
        fi
        kubectl wait --for=condition=available -n kubeflow deployment/model-registry-deployment --timeout=600s
    - name: Test KF Model Registry UI deployment
      run: |
        echo "Waiting for all Model Registry UI Pods to become ready..."
        if ! kubectl wait --for=condition=available -n kubeflow deployment/model-registry-ui --timeout=600s ; then
            kubectl events -A
            kubectl describe deployment/model-registry-ui -n kubeflow
            kubectl logs deployment/model-registry-ui -n kubeflow
            exit 1
        fi
    - name: Dry-run KF Model Registry API directly
      run: |
        echo "Dry-run KF Model Registry API directly..."
        nohup kubectl port-forward svc/model-registry-service -n kubeflow 8081:8080 &
        while ! curl localhost:8081; do echo "waiting for port-forwarding 8081"; sleep 1; done; echo "port-forwarding 8181 ready"
        curl -v -X 'GET' \
          'http://localhost:8081/api/model_registry/v1alpha3/registered_models?pageSize=100&orderBy=ID&sortOrder=DESC' \
          -H 'accept: application/json'

    # for these steps below ensure same steps as kserve (ie: Istio with external authentication, cert-manager, knative) so to achieve same setup
    - name: Port forward Istio gateway
      run: |
        INGRESS_GATEWAY_SERVICE=$(kubectl get svc --namespace istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}')
        nohup kubectl port-forward --namespace istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080:80 &
        while ! curl localhost:8080; do echo waiting for port-forwarding; sleep 1; done; echo port-forwarding ready

    - name: Dry-run KF Model Registry REST API
      run: |
        echo "Dry-run KF Model Registry REST API..."
        export KF_TOKEN="$(kubectl -n default create token default)"
        curl -v -H "Authorization: Bearer "$KF_TOKEN http://localhost:8080/api/model_registry/v1alpha3/registered_models

    - name: Dry-run KF Model Registry REST API UI
      run: |
        echo "Dry-run KF Model Registry REST API..."
        export KF_PROFILE=kubeflow-user-example-com
        export KF_TOKEN="$(kubectl -n $KF_PROFILE create token default-editor)"

        STATUS_CODE=$(curl -v \
            --silent --output /dev/stderr --write-out "%{http_code}" \
            "localhost:8080/model-registry/api/v1/model_registry?namespace=${KF_PROFILE}" \
            -H "Authorization: Bearer ${KF_TOKEN}")

        if test $STATUS_CODE -ne 200; then
            echo "Error, this call should be authorized to list model registries in namespace ${KF_PROFILE}."
            exit 1
        fi

    - name: Dry-run KF Model Registry REST API UI with unauthorized SA Token
      run: |
        echo "Dry-run KF Model Registry REST API..."
        export KF_PROFILE=kubeflow-user-example-com
        export KF_TOKEN="$(kubectl -n default create token default)"

        STATUS_CODE=$(curl -v \
            --silent --output /dev/stderr --write-out "%{http_code}" \
            "localhost:8080/model-registry/api/v1/model_registry?namespace=${KF_PROFILE}" \
            -H "Authorization: Bearer ${KF_TOKEN}")

        if test $STATUS_CODE -ne 403; then
            echo "Error, this call should fail to list model registry resources in namespace ${KF_PROFILE}."
            exit 1
        fi
