Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion api/.markdownlintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
out/
vendor/
venv_api/
test/README.md
363 changes: 25 additions & 338 deletions api/test/README.md
Original file line number Diff line number Diff line change
@@ -1,367 +1,54 @@
# Integration Tests

TODO: UPDATE GUIDE
This file describes how to execute the integration tests placed in this folder.

> These tests do not delete created Hosts from the Inventory, which means that some tests may fail, if you run them two
times in a row.
> To avoid that, please either re-deploy API and Inventory, or use `hostcli` to delete duplicated/unnecessary hosts

## Requirements

It requires helm and kubectl installed, besides an operational Kubernetes cluster.

## Run

Clone and deploy the Edge Infrastructure Manager chart, with api, topology and inventory
components enabled, check the values.yaml file or use --set flags.

> `Authentication` functionality is disabled by default, don't forget to enable it in the charts.

```bash
git clone https://github.com/open-edge-platform/infra-charts
cd infra-charts
make deps
kubectl create ns orch-infra
helm -n orch-infra install --set api.oidc.oidc_server_url="http://platform-keycloak.orch-platform:8080/realms/master" --set inventory.oidc.oidc_server_url="http://platform-keycloak.orch-platform:8080/realms/master" infra-core ./infra-core
```

Deploy a Keycloak instance with all dependencies:

```bash
TODO: add instructions
```

Wait until all pods are in running state.

```bash
kubectl -n orch-infra get pods
kubectl -n orch-platform get pods
```

Then enable a port-forward to have interface with the API component via port 8080.

```bash
kubectl -n orch-infra port-forward svc/api 8080
```

Enable port-forwarding for the `Keycloak`.

```bash
kubectl -n orch-platform port-forward service/platform-keycloak 8090:8080
```

Credentials to access `Keycloak` can be found in `values.yaml` of a `Keycloak` deployment (they usually are `admin/ChangeMeOn1stLogin!`),

Now, you are almost good to go. In another terminal run the following command to obtain a valid JWT:

```bash
curl --location --request POST 'http://localhost:8090/realms/master/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=system-client' \
--data-urlencode 'username=admin' \
--data-urlencode 'password=ChangeMeOn1stLogin!' \
--data-urlencode 'scope=openid profile email groups'
```

Extract from the response an `access_token` field and export it as an environmental variable `JWT_TOKEN` in your terminal:

```bash
export JWT_TOKEN=jwt-token-obtained-from-keycloak
```

In the same terminal run the tests:

```bash
go test -v ./test/client/

# To run a specific test, define the -run flag
# go test -v ./test/client/ -run TestComputeHost
```

## Trace Test Case

This test case is for demonstration of features only.
It must not be used as a routine test case for API.

The Edge Infrastructure Manager chart components must be deployed with the following values set:

```yaml
traceURL: "observability-opentelemetry-collector.orch-platform.svc:4318"
enableTracing: true
```

This test case presents how a client can be enabled to
add its tracing information inside the requests done to
the API component.

To make it work, it requires that at least Edge Infrastructure API and
inventory components are deployed, together with some
observability parts of Edge Infrastructure Manager deployment, listed below.

```yaml
- 02-mp-prometheus.yaml
- 11-mp-kube-prometheus-stack.yaml
- 12-mp-observability.yaml
```

After the deployment of those charts it requires that
port-forward is enabled for the following services.

```bash
kubectl -n orch-infra port-forward svc/api 8080
kubectl -n orch-platform port-forward svc/observability-opentelemetry-collector 4318
```
It requires golang and kubectl installed, besides an operational Kubernetes cluster
with EMF (Edge Manageability Framework) deployed.

The test can be executed with the following command
The tests consider to have access to the cluster.

```bash
go test -v -count=1 ./test/client -run TestTraceWithRegion
```
# Set variables needed for the tests
export KEYCLOAK_URL="https://keycloak.kind.internal"
export PASSWORD='ChangeMeOn1stLogin!'
export USERNAME="sample-project-api-user"
export API_URL="http://127.0.0.1:8080/edge-infra.orchestrator.apis/v1"
export CA_PATH="orch-ca.crt"

After the execution it is possible to visualizing the
traces in the grafana explore section, selecting the `Tempo` source.
Log into the grafana (e.g., `https://observability-admin.kind.internal/`) by using the credentials:
PROJECT_ID=$(kubectl get projects.project -o json | jq -r ".items[0].status.projectStatus.uID")

```bash
user: admin
password: kubectl -n orch-platform get secret kube-prometheus-stack-grafana-admin -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
JWT_TOKEN=$(curl -k --location --request POST ${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=password' --data-urlencode 'client_id=system-client' --data-urlencode username=${USERNAME} --data-urlencode password=${PASSWORD} --data-urlencode 'scope=openid profile email groups' | jq -r '.access_token')
```

In the logs presented in the output of the test case
it should contain a `trace_id` field, copy and paste
that value in the tempo search for a trace-id.
After running the query it should display all the
calls done from the client and its related spans in
api and inventory components.
The integration tests require access to the Infrastructure Manager REST API,
the the project ID which is associated with the USERNAME,
the path of the cluster CA file, and the JWT token associated with the USERNAME credentials.

## Run test with Edge Infrastructure Manager deployment
Notice: change the names of the variables according to your deployment setup.

Download Edge Infrastructure Manager deployment repo.
## Run

To deploy minimal Edge Infrastructure environment:
Then enable a port-forward to have interface with the API component via port 8080.

```bash
source features/min-infra.env
mage -v deploy:kindAll
kubectl port-forward svc/api -n orch-infra --address 0.0.0.0 8080:8080 &
```

Retrieve a token from Platform Keycloak:
Run the integration tests:

```bash
export JWT_TOKEN=`curl -s --location --request POST 'https://keycloak.kind.internal/realms/master/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=system-client' \
--data-urlencode 'username=lp-admin' \
--data-urlencode 'password=ChangeMeOn1stLogin!' \
--data-urlencode 'scope=openid profile email groups' | jq .access_token`
# A test case can be specified after the `go test` statement, such as: -run TestHostCustom
JWT_TOKEN=${JWT_TOKEN} PROJECT_ID=${PROJECT_ID} go test -v -count=1 ./test/client/ -apiurl=${API_URL} -caPath=${CA_PATH}
```

Run integration tests:
or using Make target:

```bash
TODO: update URL with MT GW
go test -count=1 -failfast -v ./test/client/ -apiurl=https://[API_URL]/edge-infra.orchestrator.apis/v1/ -run TestHostInvalidate
make int-test JWT_TOKEN=${JWT_TOKEN} PROJECT_ID=${PROJECT_ID} API_URL=${API_URL} CA_PATH=${CA_PATH}
```

or using Make target:
Kill the port-forward command:

```bash
TODO: use new MT GW API.
make int-test-host API_URL="https://api.kind.internal/edge-infra.orchestrator.apis/v1/"
kill $(ps -eaf | grep 'kubectl' | grep 'port-forward svc/api' | awk '{print $2}')
```

## Run test with Edge Infrastructure Manager deployment in Coder environment

1. Deploy Edge Infrastructure Manager in Coder environment. Follow the steps in
[Orchestrator Deployment in Coder][coder-deployment] guide.

2. Set the following environment variables:

```bash
ADMIN_USER=all-groups-example-user
ADMIN_PASS=ChangeMeOn1stLogin!
CLUSTER_FQDN=kind.internal
ORG_NAME=example-org
ORG_ADMIN_USER=${ORG_NAME}-admin
ORG_ADMIN_PASS=ChangeMeOn1stLogin!
PROJ_NAME=example-proj
PROJ_ADMIN_USER=${PROJ_NAME}-admin
PROJ_ADMIN_PASS=ChangeMeOn1stLogin!
CUSTOMER_ID=1234567
PRODUCT_KEY=1234567
```

**Note:** Ensure that `$ADMIN_USER` is joined to the `Org-Admin-Group` Keycloak group - this can be done through
Keycloak web-ui: `https://keycloak.${CLUSTER_FQDN}/`.

3. Retrieve a JWT token from Keycloak:

```bash
JWT_TOKEN=$(curl -s --location --request POST https://keycloak.${CLUSTER_FQDN}/realms/master/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=system-client' \
--data-urlencode "username=${ADMIN_USER}" \
--data-urlencode "password=${ADMIN_PASS}" \
--data-urlencode 'scope=openid profile email groups' | jq -r .access_token)
```

4. Create a new org via MT APIs

```bash
curl -X PUT "https://api.${CLUSTER_FQDN}/v1/orgs/${ORG_NAME}" -H "accept: application/json" -H "Authorization: Bearer ${JWT_TOKEN}" -H "Content-Type: application/json" -d "{\"description\":\"${ORG_NAME}\"}"

ORG_UUID=$(curl --location https://api.${CLUSTER_FQDN}/v1/orgs/${ORG_NAME} -H "accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .orgStatus.uID)
```

5. Create a license for the new org

```bash
curl -X PUT https://api.${CLUSTER_FQDN}/v1/orgs/${ORG_NAME}/licenses/enlicense -H "accept: application/json" -H "Authorization: Bearer ${JWT_TOKEN}" -H "Content-Type: application/json" -d "{\"customerID\":\"${CUSTOMER_ID}\",\"productKey\":\"${PRODUCT_KEY}\"}"
```

6. Create an admin user for the org

```bash
curl -X POST "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-d '{
"username": "'${ORG_ADMIN_USER}'",
"enabled": true,
"emailVerified": true,
"credentials": [{
"type": "password",
"value": "'${ORG_ADMIN_PASS}'",
"temporary": false
}]
}'

ORG_ADMIN_USER_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users?username=${ORG_ADMIN_USER}" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r '.[0].id')

ORG_PROJMGR_GROUP_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/groups?search=${ORG_UUID}_Project-Manager-Group" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r '.[0].id')

curl -X PUT "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users/${ORG_ADMIN_USER_ID}/groups/${ORG_PROJMGR_GROUP_ID}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'

ORG_JWT_TOKEN=$(curl -s --location --request POST https://keycloak.${CLUSTER_FQDN}/realms/master/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=system-client' \
--data-urlencode "username=${ORG_ADMIN_USER}" \
--data-urlencode "password=${ORG_ADMIN_PASS}" \
--data-urlencode 'scope=openid profile email groups' | jq -r .access_token)
```

7. Create a project for the org

```bash
curl -X PUT https://api.${CLUSTER_FQDN}/v1/projects/${PROJ_NAME} -H "accept: application/json" -H "Authorization: Bearer ${ORG_JWT_TOKEN}" -H "Content-Type: application/json" -d "{\"description\":\"${PROJ_NAME}\"}"

PROJ_UUID=$(curl --location https://api.${CLUSTER_FQDN}/v1/projects/${PROJ_NAME} -H "accept: application/json" -H "Content-Type: application" -H "Authorization: Bearer ${ORG_JWT_TOKEN}" | jq -r .projectStatus.uID)
```

8. Wait for the project to be provisioned in the orchestrator

```bash
while [ "$(curl -s --location https://api.${CLUSTER_FQDN}/v1/projects/${PROJ_NAME} -H "accept: application/json" -H "Content-Type: application" -H "Authorization: Bearer ${ORG_JWT_TOKEN}" | jq -r .projectStatus.statusIndicator)" != "STATUS_INDICATION_IDLE" ]; do
echo "Waiting for ${PROJ_NAME} to be provisioned..."
sleep 5
done
```

9. Create admin user for the project

```bash
curl -X POST "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-d '{
"username": "'${PROJ_ADMIN_USER}'",
"enabled": true,
"emailVerified": true,
"credentials": [{
"type": "password",
"value": "'${PROJ_ADMIN_PASS}'",
"temporary": false
}]
}'

PROJ_ADMIN_USER_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users?username=${PROJ_ADMIN_USER}" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .[0].id)

PROJ_EDGE_MANAGER_GROUP_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/groups?search=${PROJ_UUID}_Edge-Manager-Group" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .[0].id)

PROJ_EDGE_ONB_GROUP_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/groups?search=${PROJ_UUID}_Edge-Onboarding-Group" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .[0].id)

PROJ_EDGE_OP_GROUP_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/groups?search=${PROJ_UUID}_Edge-Operator-Group" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .[0].id)

PROJ_HOST_MGR_GROUP_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/groups?search=${PROJ_UUID}_Host-Manager-Group" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .[0].id)

PROJ_MGR_GROUP_ID=$(curl -X GET "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/groups?search=${ORG_UUID}_Project-Manager-Group" -H "Authorization: Bearer ${JWT_TOKEN}" | jq -r .[0].id)

curl -X PUT "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users/${PROJ_ADMIN_USER_ID}/groups/${PROJ_EDGE_MANAGER_GROUP_ID}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'

curl -X PUT "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users/${PROJ_ADMIN_USER_ID}/groups/${PROJ_EDGE_ONB_GROUP_ID}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'

curl -X PUT "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users/${PROJ_ADMIN_USER_ID}/groups/${PROJ_EDGE_OP_GROUP_ID}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'

curl -X PUT "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users/${PROJ_ADMIN_USER_ID}/groups/${PROJ_HOST_MGR_GROUP_ID}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'

curl -X PUT "https://keycloak.${CLUSTER_FQDN}/admin/realms/master/users/${PROJ_ADMIN_USER_ID}/groups/${PROJ_MGR_GROUP_ID}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}'
```

10. Obtain JWT token of the project admin and set project-id to run the integration tests with MT-awareness:

```bash
ORG_JWT_TOKEN=$(curl -s --location --request POST https://keycloak.${CLUSTER_FQDN}/realms/master/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=system-client' \
--data-urlencode "username=${ORG_ADMIN_USER}" \
--data-urlencode "password=${ORG_ADMIN_PASS}" \
--data-urlencode 'scope=openid profile email groups' | jq -r .access_token)
export PROJECT_ID=$(curl --location https://api.${CLUSTER_FQDN}/v1/projects/${PROJ_NAME} -H "accept: application/json" -H "Content-Type: application" -H "Authorization: Bearer ${ORG_JWT_TOKEN}" | jq -r .projectStatus.uID)
export JWT_TOKEN=$(curl -s --location --request POST https://keycloak.${CLUSTER_FQDN}/realms/master/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=system-client' \
--data-urlencode "username=${PROJ_ADMIN_USER}" \
--data-urlencode "password=${PROJ_ADMIN_PASS}" \
--data-urlencode 'scope=openid profile email groups' | jq -r .access_token)
```

11. Run integration tests:

```bash
TODO: update URL with MT GW
go test -count=1 -failfast -v ./test/client/ -apiurl=https://[API_URL].kind.internal/edge-infra.orchestrator.apis/v1/ -run TestHostInvalidate
```

or using Make target:

```bash
TODO: update URL with MT GW
make int-test-host API_URL="https://[API_URL]/edge-infra.orchestrator.apis/v1/"
```

[coder-deployment]: TODO: Add link to guide for coder deployment
Loading