Release K: Testing - K8S Etsi OCF Capif
Repository: https://labs.etsi.org/rep/ocf/capif
Wiki: https://labs.etsi.org/rep/groups/ocf/-/wikis/home
(Note: This page uses a version of OCF from Dec 2024 - and is likely out of date by now)
Openshift Helm Capif Installation
Unpack this helm.tar, and it will have modified scripts to install OCF on OpenShift.
Navigate to scripts folder
export KUBECONFIG="$HOME/.kube"
tar xf helm.tar
cd helm/scripts/
./install_vault.sh
sed -i 's/export VAULT_TOKEN=""/export VAULT_TOKEN="root"/' vault-job/vault-job.yaml
./install_capif.shOr MANUALLY install the main components:
Install Ingress NGINX with RBAC and ssl-passthrough
#############################################################
#################### INSTALL CAPIF NGINX ####################
#############################################################
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--set rbac.create=true \
--set controller.service.type=NodePort \
--set controller.service.nodePorts.http=32080 \
--set controller.service.nodePorts.https=32443 \
--namespace ingress-nginx --create-namespace \
--set controller.extraArgs."enable-ssl-passthrough=true" \
--kubeconfig $KUBECONFIGOCF uses Vault to do secret management. There are some particular settings for Openshift:
https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-openshift
#############################################################
#################### INSTALL CAPIF VAULT ####################
#############################################################
helm $KUBECONFIG upgrade --install vault hashicorp/vault -n ocf-vault \
--set server.ingress.enabled=true \
--set server.ingress.hosts[0].host="vault.testbed.develop" \
--set server.ingress.ingressClassName=nginx \
--set server.standalone.enabled=true --create-namespace \
--set "global.openshift=true" \
--set "server.dev.enabled=true" \
--set "server.image.repository=docker.io/hashicorp/vault" \
--set "injector.image.repository=docker.io/hashicorp/vault-k8s"Log the vault pod and get the tokens, usually on OpenShift the admin token is root, but the unseal key is generated.
kubectl $KUBECONFIG logs vault-0 -n ocf-vault
kubectl $KUBECONFIG exec -it vault-0 -n ocf-vault -- vault operator unseal 19zgCoVzIC4665WfRAD7gJmHTTXtqRfYrltjJ7u77AA=Manually create PV and PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: tempo-pv
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data/tempo"
EOF
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tempo-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
EOFSet Some Variables:
$CAPIF_NAMESPACE
$CAPIF_NAME_VERSION_CHART
$HELM_DIR
$CAPIF_DOCKER_REGISTRY
$CAPIF_IMAGE_TAG
$VAULT_PORT
$VAULT_ACCESS_TOKEN
$VAULT_INTERNAL_HOSTNAME
Install CAPIF
helm $KUBECONFIG upgrade --install -n $CAPIF_NAMESPACE $CAPIF_NAME_VERSION_CHART $HELM_DIR/capif/ \
--set ocf-access-control-policy.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-access-control-policy-api \
--set ocf-access-control-policy.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-access-control-policy.image.env.capifHostname=$CAPIF_HOSTNAME \
--set ocf-access-control-policy.monitoring="true" \
--set ocf-access-control-policy.env.logLevel="DEBUG" \
--set ocf-api-invocation-logs.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-logging-api-invocation-api \
--set ocf-api-invocation-logs.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-api-invocation-logs.env.monitoring="true" \
--set ocf-api-invocation-logs.env.capifHostname=$CAPIF_HOSTNAME \
--set ocf-api-invocation-logs.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set ocf-api-invocation-logs.env.vaultPort=$VAULT_PORT \
--set ocf-api-invocation-logs.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set ocf-api-invocation-logs.env.logLevel="DEBUG" \
--set ocf-api-invoker-management.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-api-invoker-management-api \
--set ocf-api-invoker-management.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-api-invoker-management.env.monitoring="true" \
--set ocf-api-invoker-management.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set ocf-api-invoker-management.env.vaultPort=$VAULT_PORT \
--set ocf-api-invoker-management.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set ocf-api-invoker-management.env.logLevel="DEBUG" \
--set ocf-api-provider-management.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-api-provider-management-api \
--set ocf-api-provider-management.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-api-provider-management.env.monitoring="true" \
--set ocf-api-provider-management.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set ocf-api-provider-management.env.logLevel="DEBUG" \
--set ocf-api-provider-management.env.vaultPort=$VAULT_PORT \
--set ocf-api-provider-management.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set ocf-events.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-events-api \
--set ocf-events.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-events.env.monitoring="true" \
--set ocf-events.env.logLevel="DEBUG" \
--set ocf-routing-info.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-routing-info-api \
--set ocf-routing-info.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-routing-info.env.monitoring="true" \
--set ocf-routing-info.env.logLevel="DEBUG" \
--set ocf-security.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-security-api \
--set ocf-security.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-security.env.monitoring="true" \
--set ocf-security.env.capifHostname=$CAPIF_HOSTNAME \
--set ocf-security.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set ocf-security.env.vaultPort=$VAULT_PORT \
--set ocf-security.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set ocf-security.env.logLevel="DEBUG" \
--set ocf-register.image.repository=$CAPIF_DOCKER_REGISTRY/register \
--set ocf-register.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-register.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set ocf-register.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set ocf-register.env.vaultPort=$VAULT_PORT \
--set ocf-register.env.mongoHost=mongo-register \
--set ocf-register.env.mongoPort=27017 \
--set ocf-register.env.capifHostname=$CAPIF_HOSTNAME \
--set ocf-register.ingress.enabled=true \
--set ocf-register.ingress.hosts[0].host=$REGISTER_HOSTNAME \
--set ocf-register.ingress.hosts[0].paths[0].path="/" \
--set ocf-register.ingress.hosts[0].paths[0].pathType="Prefix" \
--set ocf-register.env.logLevel="DEBUG" \
--set ocf-register.extraConfigPod.hostAliases[0].hostnames[0]=$CAPIF_HOSTNAME \
--set ocf-register.extraConfigPod.hostAliases[0].ip=$K8S_IP \
--set ocf-auditing-api-logs.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-auditing-api \
--set ocf-auditing-api-logs.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-auditing-api-logs.env.monitoring="true" \
--set ocf-auditing-api-logs.env.logLevel="DEBUG" \
--set ocf-publish-service-api.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-publish-service-api \
--set ocf-publish-service-api.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-publish-service-api.env.monitoring="true" \
--set ocf-publish-service-api.env.logLevel="DEBUG" \
--set ocf-discover-service-api.image.repository=$CAPIF_DOCKER_REGISTRY/ocf-discover-service-api \
--set ocf-discover-service-api.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-discover-service-api.env.monitoring="true" \
--set ocf-discover-service-api.env.logLevel="DEBUG" \
--set nginx.image.repository=$CAPIF_DOCKER_REGISTRY/nginx \
--set nginx.image.tag=$CAPIF_IMAGE_TAG \
--set nginx.env.capifHostname=$CAPIF_HOSTNAME \
--set nginx.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set nginx.env.vaultPort=$VAULT_PORT \
--set nginx.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set nginx.ingress.enabled=true \
--set nginx.ingress.hosts[0].host=$CAPIF_HOSTNAME \
--set nginx.ingress.hosts[0].paths[0].path="/" \
--set nginx.ingress.hosts[0].paths[0].pathType="Prefix" \
--set nginx.nginx.env.capifHostname=$CAPIF_HOSTNAME \
--set ingress_ip.oneke="$INGRESS_IP" \
--set nginx.env.logLevel="debug" \
--set ocf-helper.image.repository=$CAPIF_DOCKER_REGISTRY/helper \
--set ocf-helper.image.tag=$CAPIF_IMAGE_TAG \
--set ocf-helper.env.vaultHostname=$VAULT_INTERNAL_HOSTNAME \
--set ocf-helper.env.vaultPort=$VAULT_PORT \
--set ocf-helper.env.vaultAccessToken=$VAULT_ACCESS_TOKEN \
--set ocf-helper.env.capifHostname=$CAPIF_HOSTNAME \
--set ocf-helper.env.logLevel="DEBUG" \
--wait --timeout=10m --create-namespaceManually Retrieve a Bearer Token
Login as an admin (admin:password123 or encoded “
YWRtaW46cGFzc3dvcmQxMjM=“) and retrieve a TOKENUse the TOKEN to create a normal user
Get Authorization and ACCESS_TOKEN for the user and the CA_ROOT
Prepare a PROVIDER with keys in body and authenticate with the ACCESS_TOKEN
ONBOARD that PROVIDER
#!/bin/bash
if ! command -v "jq" >/dev/null 2>&1; then
echo "Error: jq is not installed. Please install jq and try again."
exit 1
fi
export INGRESS_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller | grep ingress | awk '{print $3}')
echo "INGRESS_IP: $INGRESS_IP"
CAPIF_HOSTNAME=$INGRESS_IP
# Retrieve the REGISTER_IP
export REGISTER_IP=$(kubectl get svc -n ocf-capif register | grep register | awk '{print $3}')
echo "REGISTER_IP: $REGISTER_IP"
# Retrieve the NGINX_IP
export NGINX_IP=$(kubectl get svc -n ocf-capif nginx | grep nginx | awk '{print $3}')
echo "NGINX_IP: $NGINX_IP"
echo "###############################################################"
echo "###################ADMIN LOGIN#################################"
echo "###############################################################"
# Log in and extract the Bearer token
LOGIN_RESPONSE=$(curl -s -k -X POST https://$REGISTER_IP:8084/login \
--header 'Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=')
BEARER_TOKEN=$(echo $LOGIN_RESPONSE | jq -r .access_token)
echo "Bearer Token: $BEARER_TOKEN"
echo "###############################################################"
echo "###################CREATE A USER###############################"
echo "###############################################################"
# Create a new user
curl -k --location https://$REGISTER_IP:8084/createUser \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $BEARER_TOKEN" \
--data-raw '{
"username": "custom_user",
"password": "user_pass",
"enterprise": "EST",
"country": "Ireland",
"email": "est@est.tech",
"purpose": "Use OpenCAPIF",
"phone_number": "+123456789",
"company_web": "www.est.com",
"description": "UserDescription"
}'
echo "###############################################################"
echo "###################GET AUTH####################################"
echo "###############################################################"
# Retrieve auth credentials for the newly created user
GET_AUTH_RESPONSE=$(curl -s -k --location https://$REGISTER_IP:8084/getauth \
--header 'Authorization: Basic Y3VzdG9tX3VzZXI6dXNlcl9wYXNz')
# Parse and set environment variables from the response
CA_ROOT=$(echo $GET_AUTH_RESPONSE | jq -r .ca_root)
ACCESS_TOKEN=$(echo $GET_AUTH_RESPONSE | jq -r .access_token)
ONBOARDING_URL=$(echo $GET_AUTH_RESPONSE | jq -r .ccf_api_onboarding_url)
PUBLISH_URL=$(echo $GET_AUTH_RESPONSE | jq -r .ccf_publish_url)
DISCOVER_URL=$(echo $GET_AUTH_RESPONSE | jq -r .ccf_discover_url)
SECURITY_URL=$(echo $GET_AUTH_RESPONSE | jq -r .ccf_security_url)
ONBOARDING_URL_INVOKER=$(echo $GET_AUTH_RESPONSE | jq -r .ccf_onboarding_url)
# Print extracted values
echo "CA_ROOT: $CA_ROOT"
echo "ACCESS_TOKEN: $ACCESS_TOKEN"
echo "ONBOARDING_URL: $ONBOARDING_URL"
echo "PUBLISH_URL: $PUBLISH_URL"
echo "DISCOVER_URL: $DISCOVER_URL"
echo "SECURITY_URL: $SECURITY_URL"
echo "ONBOARDING_URL_INVOKER: $ONBOARDING_URL_INVOKER"
# Save CA_ROOT to a file (manual extraction)
CA_CERT_PATH="./ca_cert.pem"
echo "$CA_ROOT" > $CA_CERT_PATH
echo "CA Root Certificate saved to $CA_CERT_PATH"
# Extract OpenSSL command for the CAPIF_HOSTNAME
if [[ "$CAPIF_HOSTNAME" == *:* ]]; then
OPENSSL_COMMAND="openssl s_client -connect $CAPIF_HOSTNAME | openssl x509 -text > $CA_CERT_PATH"
else
OPENSSL_COMMAND="openssl s_client -connect $CAPIF_HOSTNAME:443 | openssl x509 -text > $CA_CERT_PATH"
fi
# Execute the OpenSSL command
echo "###############################################################"
echo "###################OPENSSL COMMAND TO EXTRACT CAROOT###########"
echo "###############################################################"
echo "Executing OpenSSL command to fetch CA root certificate:"
eval $OPENSSL_COMMAND
echo "OpenSSL command executed. Certificate updated."
echo "###############################################################"
echo "###################PREPARE PROVIDER############################"
echo "###############################################################"
# Initial payload
EMPTY_PAYLOAD='{
"apiProvFuncs": [
{
"regInfo": {
"apiProvPubKey": ""
},
"apiProvFuncRole": "AEF",
"apiProvFuncInfo": "dummy_aef"
},
{
"regInfo": {
"apiProvPubKey": ""
},
"apiProvFuncRole": "APF",
"apiProvFuncInfo": "dummy_apf"
},
{
"regInfo": {
"apiProvPubKey": ""
},
"apiProvFuncRole": "AMF",
"apiProvFuncInfo": "dummy_amf"
}
],
"apiProvDomInfo": "This is provider",
"suppFeat": "fff",
"failReason": "string",
"regSec": "'"$ACCESS_TOKEN"'"
}'
# Extract the list of API Provider functions as an array
API_PROV_FUNCS=$(echo "$EMPTY_PAYLOAD" | jq -c '.apiProvFuncs[]')
# Initialize an updated functions array
UPDATED_FUNCS_JSON="[]"
# Iterate over each API Provider function
for FUNC in $API_PROV_FUNCS; do
ROLE=$(echo "$FUNC" | jq -r '.apiProvFuncRole')
FUNC_INFO=$(echo "$FUNC" | jq -r '.apiProvFuncInfo')
# Generate a private key and save it to a file
PRIVATE_KEY_FILE="${ROLE}_key.pem"
openssl genpkey -algorithm RSA -out "$PRIVATE_KEY_FILE" -pkeyopt rsa_keygen_bits:2048
# Generate a CSR using the private key
CSR_FILE="${ROLE}_csr.pem"
openssl req -new -key "$PRIVATE_KEY_FILE" -out "$CSR_FILE" -subj "/CN=${FUNC_INFO}/O=Provider/OU=${ROLE}"
# Read the CSR content
#CSR=$(cat "$CSR_FILE" | base64 | tr -d '\n')
CSR=$(cat "$CSR_FILE")
# Update the function's Public Key with the CSR content
UPDATED_FUNC=$(echo "$FUNC" | jq --arg csr "$CSR" '.regInfo.apiProvPubKey = $csr')
# Add the updated function to the array
UPDATED_FUNCS_JSON=$(echo "$UPDATED_FUNCS_JSON" | jq --argjson func "$UPDATED_FUNC" '. + [$func]')
done
# Create the final payload
FINAL_PAYLOAD=$(echo "$EMPTY_PAYLOAD" | jq --argjson funcs "$UPDATED_FUNCS_JSON" '.apiProvFuncs = $funcs')
# Print the final payload
echo "Final Payload: $FINAL_PAYLOAD"
echo "###############################################################"
echo "###################ONBOARD PROVIDER############################"
echo "###############################################################"
curl -k --location https://$NGINX_IP/api-provider-management/v1/registrations \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--data "$FINAL_PAYLOAD"
echo "###############################################################"
echo "###################K8S PROVIDER LOGS###########################"
echo "###############################################################"
kubectl logs -n ocf-capif -l app.kubernetes.io/name=ocf-api-provider-management
TBD
SME only installation
kubectl create ns nonrtric
helm install -n nonrtric kongstorage ./kongstorage
helm repo add kong https://charts.konghq.com --force-update
helm repo update
helm install -n nonrtric oran-nonrtric kong/kong -f ./kongstorage/kongvalues.yaml
helm install -n nonrtric r3-dev-nonrtric ./servicemanager