Skip to content

Commit

Permalink
run maestro with rosa
Browse files Browse the repository at this point in the history
Signed-off-by: Wei Liu <liuweixa@redhat.com>
  • Loading branch information
skeeey committed Nov 5, 2024
1 parent 42899b6 commit 702801c
Show file tree
Hide file tree
Showing 9 changed files with 560 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ hack/mosquitto-passwd.txt
vendor/

# Ignore test data
_output
test/e2e/.kubeconfig
test/e2e/.consumer_id
test/e2e/.consumer_name
test/e2e/.external_host_ip
test/e2e/report/*
unit-test-results.json
integration-test-results.json

test/e2e/setup/aro/aro-hcp
test/e2e/setup/aro/aro-hcp
30 changes: 30 additions & 0 deletions test/e2e/setup/rosa/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
SHELL:=/bin/bash

e2e_dir=$(shell cd ${PWD}/../.. && pwd -P)

rosa/setup-maestro:
./setup/maestro.sh
.PHONY: rosa/setup-maestro

rosa/setup-agent:
./setup/agent.sh
.PHONY: rosa/setup-agent

rosa/setup-e2e:
./setup/e2e.sh
.PHONY: rosa/setup-e2e

rosa/e2e-test: rosa/setup-e2e
ginkgo -v --fail-fast --label-filter="!(e2e-tests-spec-resync-reconnect||e2e-tests-status-resync-reconnect)" \
--output-dir="$(e2e_dir)/report" --json-report=report.json --junit-report=report.xml \
${e2e_dir}/pkg -- \
-api-server="http://127.0.0.1:8000" \
-grpc-server="127.0.0.1:8090" \
-server-kubeconfig=$(KUBECONFIG) \
-agent-kubeconfig=$(KUBECONFIG) \
-consumer-name=${PWD}/_output/consumer_id
.PHONY: rosa/e2e-test

rosa/teardown:
./setup/teardown.sh
.PHONY: rosa/teardown
91 changes: 91 additions & 0 deletions test/e2e/setup/rosa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Setup

## Setup Maestro server and agent

This setup demonstrate how to deploy the Maestro with AWS IoT and AWS RDS PostgreSQL.

1. Run following command to deploy a Maestro server on a given cluster

```sh
export AWS_IOT_REGION="<your_aws_iot_region>"
export CLUSTER_REGION="<your_cluster_region>"
export CLUSTER_VPC="<your_cluster_vpc>"
export KUBECONFIG="<your_cluster_kubeconfig>"

make rosa/setup-maestro
```

This will
- Create AWS IoT client certs and policy for Maestro server in the given AWS IoT region
- Create AWS RDS PostgreSQL for Maestro server in the given cluster region
- Deploy the Maestro server on the given cluster

After the Maestro server is deployed, you can run following commands to start the Maestro RESTful service and GRPC service in your local host

```sh
oc port-forward svc/maestro 8000 -n maestro
oc port-forward svc/maestro-grpc 8090 -n maestro
```

Then you can create a consumer in the Maestro, e.g.

```sh
curl -s -X POST -H "Content-Type: application/json" http://127.0.0.1:8000/api/maestro/v1/consumers -d '{}'
```

2. Run following command to deploy a Maestro agent on a given cluster

```sh
export AWS_IOT_REGION="<your_aws_iot_region>" # Note: this region should be same with the above aws iot region
export CONSUMER_ID="<your_maestro_consumer_id_or_name>"
export KUBECONFIG="<your_cluster_kubeconfig>"

make rosa/setup-agent
```

This will
- Create AWS IoT client certs and policy for Maestro agent in the given AWS IoT region
- Deploy the Maestro agent on the given cluster

## Run a Maestro e2e on a ROSA cluster

### Prepare

1. Install the following CLIs
- `oc`
- `rosa`
- `aws`
- `jq`
- the [`krelay` plugin](https://github.com/knight42/krelay)

2. Create a rosa cluster, for example

```sh
rosa create cluster --cluster-name=maestro-rosa-e2e --region=us-west-2 --sts --mode=auto
```

### Run Maestro e2e

```sh
export KUBECONFIG="<your_rosa_cluster_kubeconfig>"
export REGION="<your_rosa_cluster_region>"
export CLUSTER_ID="<your_rosa_cluster_name_or_id>"

make rosa/e2e-test
```

### Cleanup

1. Run following commands to cleanup the AWS IoT and RDS resources

```sh
export REGION="<your_rosa_cluster_region>"

make rosa/teardown
```

2. Delete the ROSA cluster, for example

```sh
rosa delete cluster --cluster=maestro-rosa-e2e
```
85 changes: 85 additions & 0 deletions test/e2e/setup/rosa/setup/agent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/usr/bin/env bash

#####################
# Setup Maestro agent
#####################

PWD="$(cd "$(dirname ${BASH_SOURCE[0]})" ; pwd -P)"
ROOT_DIR="$(cd ${PWD}/.. && pwd -P)"

region=${AWS_IOT_REGION:-""}
consumer_id=${CONSUMER_ID:-""}

if [ -z "$region" ]; then
echo "aws iot region is required"
exit 1
fi

if [ -z "$consumer_id" ]; then
echo "consumer id is required"
exit 1
fi

IMAGE_REGISTRY=${IMAGE_REGISTRY:="quay.io/redhat-user-workloads/maestro-rhtap-tenant/maestro"}
IMAGE_REPOSITORY="maestro"
IMAGE_TAG=${IMAGE_TAG:-"1de63c6075f2c95c9661d790d164019f60d789f3"}

output_dir=${ROOT_DIR}/_output
certs_dir=${output_dir}/aws-certs
consumer_cert_dir=${certs_dir}/iot/consumers
policies_dir=${output_dir}/aws-policies

mkdir -p ${consumer_cert_dir}
mkdir -p ${policies_dir}

# Download AWS IoT broker severing CA
echo "Download AWS IoT broker severing CA ...."
curl -s -o ${certs_dir}/iot-ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem

# Generated client certs for AWS IoT clients
echo "Generate AWS IoT client certs for Maestro agent ...."
consumer_cert_arn=$(aws iot create-keys-and-certificate \
--region ${region} \
--set-as-active \
--certificate-pem-outfile "${consumer_cert_dir}/${consumer_id}.crt" \
--public-key-outfile "${consumer_cert_dir}/${consumer_id}.public.key" \
--private-key-outfile "${consumer_cert_dir}/${consumer_id}.private.key" | jq -r '.certificateArn')
echo "Maestro agent AWS IoT client certs are generated ($consumer_cert_arn)"

# Attach policies for AWS IoT clients
aws_account=$(aws sts get-caller-identity --region ${region} --output json | jq -r '.Account')

echo "Generate AWS IoT policy for Maestro agent ...."
cat $PWD/aws-iot-policies/consumer.template.json | sed "s/{region}/${region}/g" | sed "s/{aws_account}/${aws_account}/g" | sed "s/{consumer_id}/${consumer_id}/g" > $policies_dir/${consumer_id}.json
policy_name=$(aws iot create-policy \
--region ${region} \
--policy-name maestro-${consumer_id} \
--policy-document "file://${policies_dir}/${consumer_id}.json" | jq -r '.policyName')
aws iot attach-policy --region ${region} --policy-name maestro-${consumer_id} --target ${consumer_cert_arn}
echo "Maestro agent AWS IoT policy $policy_name is generated"

# Get AWS IoT broker endpoint
mqtt_host=$(aws iot describe-endpoint --region ${region} --endpoint-type iot:Data-ATS | jq -r '.endpointAddress')
echo "AWS IoT broke: ${mqtt_host}:8883"

sleep 30

# Deploy Maestro agent
oc create namespace maestro-agent || true
oc -n maestro-agent delete secrets maestro-agent-mqtt-creds --ignore-not-found
oc -n maestro-agent create secret generic maestro-agent-mqtt-creds \
--from-file=ca.crt="${certs_dir}/iot-ca.pem" \
--from-file=client.crt="${consumer_cert_dir}/${consumer_id}.crt" \
--from-file=client.key="${consumer_cert_dir}/${consumer_id}.private.key"

oc process --filename="https://raw.githubusercontent.com/openshift-online/maestro/refs/heads/main/templates/agent-template-rosa.yml" \
--local="true" \
--param="AGENT_NAMESPACE=maestro-agent" \
--param="CONSUMER_NAME=${consumer_id}" \
--param="IMAGE_REGISTRY=${IMAGE_REGISTRY}" \
--param="IMAGE_REPOSITORY=${IMAGE_REPOSITORY}" \
--param="IMAGE_TAG=${IMAGE_TAG}" \
--param="MQTT_HOST=${mqtt_host}" > ${output_dir}/maestro-${consumer_id}-rosa.json

oc apply -f ${output_dir}/maestro-${consumer_id}-rosa.json
oc -n maestro-agent wait deploy/maestro-agent --for condition=Available=True --timeout=300s
41 changes: 41 additions & 0 deletions test/e2e/setup/rosa/setup/aws-iot-policies/consumer.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:client/{consumer_id}-client"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Publish"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:topic/sources/maestro/consumers/{consumer_id}/agentevents"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:topicfilter/sources/maestro/consumers/{consumer_id}/sourceevents"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Receive"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:topic/sources/maestro/consumers/{consumer_id}/sourceevents"
]
}
]
}
43 changes: 43 additions & 0 deletions test/e2e/setup/rosa/setup/aws-iot-policies/source.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Publish"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:topic/sources/maestro/consumers/*/sourceevents"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:topicfilter/sources/maestro/consumers/+/agentevents",
"arn:aws:iot:{region}:{aws_account}:topicfilter/$share/statussubscribers/sources/maestro/consumers/+/agentevents"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Receive"
],
"Resource": [
"arn:aws:iot:{region}:{aws_account}:topic/sources/maestro/consumers/*/agentevents",
"arn:aws:iot:{region}:{aws_account}:topic/$share/statussubscribers/sources/maestro/consumers/*/agentevents"
]
}
]
}
45 changes: 45 additions & 0 deletions test/e2e/setup/rosa/setup/e2e.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash

#####################
# Setup Maestro e2e
#####################

PWD="$(cd "$(dirname ${BASH_SOURCE[0]})" ; pwd -P)"
ROSA_DIR="$(cd ${PWD}/.. && pwd -P)"

output_dir=${ROSA_DIR}/_output

mkdir -p $output_dir

echo "$output_dir"

# Find Maestro server vpc
rosa_infra_id=$(rosa describe cluster --region=${REGION} --cluster=${CLUSTER_ID} -ojson | jq -r '.infra_id')
vpc=$(aws ec2 describe-vpcs --region=${REGION} \
--filters Name=tag:Name,Values=${rosa_infra_id}-vpc | jq -r '.Vpcs[0].VpcId')

# Setup Maestro server
AWS_IOT_REGION=$REGION CLUSTER_REGION=$REGION CLUSTER_VPC=$vpc ${PWD}/maestro.sh
sleep 90 # wait the maestro service ready

# Start Maestro servers
exec oc relay service/maestro 8000:8000 -n maestro > ${output_dir}/maestro.svc.log 2>&1 &
maestro_server_pid=$!
echo "Maestro server started: $maestro_server_pid"
echo "$maestro_server_pid" > ${output_dir}/maestro_server.pid
exec oc relay service/maestro-grpc 8090:8090 -n maestro > ${output_dir}/maestro-grpc.svc.log 2>&1 &
maestro_grpc_server_pid=$!
echo "Maestro GRPC server started: $maestro_grpc_server_pid"
echo "$maestro_grpc_server_pid" > ${output_dir}/maestro_grpc_server.pid

# need to wait the relay build the connection before we get the consumer id
sleep 15

# Prepare a consumer
consumer_id=$(curl -s -X POST -H "Content-Type: application/json" http://127.0.0.1:8000/api/maestro/v1/consumers -d '{}' | jq -r '.id')
echo $consumer_id > ${output_dir}/consumer_id
echo "Consumer $consumer_id is created"

# Setup Maestro agent
oc apply -f https://raw.githubusercontent.com/open-cluster-management-io/api/release-0.14/work/v1/0000_00_work.open-cluster-management.io_manifestworks.crd.yaml
AWS_IOT_REGION=$REGION CONSUMER_ID=$consumer_id ${PWD}/agent.sh
Loading

0 comments on commit 702801c

Please sign in to comment.