Update the installation doc 24/13224/6
authorZhang Rong(Jon) <rong.zhang@windriver.com>
Mon, 5 Aug 2024 08:13:03 +0000 (16:13 +0800)
committerZhang Rong(Jon) <rong.zhang@windriver.com>
Mon, 5 Aug 2024 09:02:57 +0000 (17:02 +0800)
This commit update the installation doc for the J-Release

Change-Id: Ic39a380c73ce98bb10ffcaa3ceb6bbd1474c21e9
Signed-off-by: Zhang Rong(Jon) <rong.zhang@windriver.com>
docs/installation-guide.rst
docs/user-guide.rst

index 6856ea0..59b63d9 100644 (file)
@@ -1,6 +1,6 @@
 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
 .. SPDX-License-Identifier: CC-BY-4.0
-.. Copyright (C) 2021-2022 Wind River Systems, Inc.
+.. Copyright (C) 2021-2024 Wind River Systems, Inc.
 
 
 Installation Guide
@@ -58,6 +58,11 @@ Configuration and Management: `Enable ReadWriteOnce PVC Support in
 Additional
 Namespaces <https://docs.starlingx.io/storage/kubernetes/enable-readwriteonce-pvc-support-in-additional-namespaces.html#enable-readwriteonce-pvc-support-in-additional-namespaces>`__.
 
+Set up an OAuth 2.0 server and configure it to use either JWT with
+Shared Key or Token Introspection. Since the J-release, OAuth2 has
+been mandatory when starting the O2 application.
+
+
 2. Procedure
 ------------
 
@@ -95,73 +100,56 @@ You can install O-RAN O2 application on INF from the command line.
 
 6. Prepare the override ``yaml`` file.
 
-   1. Create a service account for SMO application.
+   a. Create a client on the OAuth Server.
 
-      Create a ServiceAccount which can be used to provide SMO
-      application with minimal access permission credentials.
+      Create a client on OAuth Server to provide O2 application with
+      access permission credentials.
 
-      ::
+      Here is a reference 3rd-party OAuth Server (`Keycloak <https://github.com/keycloak/keycloak>`__)
 
-         export SMO_SERVICEACCOUNT=smo1
-
-         cat <<EOF > smo-serviceaccount.yaml
-         apiVersion: rbac.authorization.k8s.io/v1
-         kind: Role
-         metadata:
-           namespace: default
-           name: pod-reader
-         rules:
-         - apiGroups: [""] # "" indicates the core API group
-           resources: ["pods"]
-           verbs: ["get", "watch", "list"]
-         ---
-         apiVersion: v1
-         kind: ServiceAccount
-         metadata:
-           name: ${SMO_SERVICEACCOUNT}
-           namespace: default
-         ---
-         apiVersion: rbac.authorization.k8s.io/v1
-         kind: RoleBinding
-         metadata:
-           name: read-pods
-           namespace: default
-         roleRef:
-           apiGroup: rbac.authorization.k8s.io
-           kind: Role
-           name: pod-reader
-         subjects:
-         - kind: ServiceAccount
-           name: ${SMO_SERVICEACCOUNT}
-           namespace: default
-         EOF
+      ::
 
-         kubectl apply -f smo-serviceaccount.yaml
+         docker run \
+            --name keycloak \
+            -p 8080:8080 \
+            -e KEYCLOAK_ADMIN=admin \
+            -e KEYCLOAK_ADMIN_PASSWORD=admin \
+            -e KC_HOSTNAME=localhost \
+            quay.io/keycloak/keycloak:latest \
+            start-dev
 
-   2. Create a secret for service account and obtain an access token.
+         docker exec -it keycloak /bin/bash
+            bash-5.1$ cd /opt/keycloak/bin
+            bash-5.1$ ./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
+            bash-5.1$ ./kcadm.sh update realms/master -s sslRequired=NONE
 
-      Create a secret with the type service-account-token and pass the
-      ServiceAccount in the annotation section as shown below:
+      When you create a client, you will get a client ID and client secret.
 
       ::
 
-         export SMO_SECRET=smo1-secret
+         OAUTH2_TOKEN_ENDPOINT=http://<3rd-party OAuth Server Address>:8080/realms/master/protocol/openid-connect/token
+         OAUTH2_CLIENT_ID=<oran-o2-client-id>
+         OAUTH2_CLIENT_SECRET=<oran-o2-client-secret>
 
-         cat <<EOF > smo-secret.yaml
-         apiVersion: v1
-         kind: Secret
-         metadata:
-           name: ${SMO_SECRET}
-           annotations:
-             kubernetes.io/service-account.name: ${SMO_SERVICEACCOUNT}
-         type: kubernetes.io/service-account-token
-         EOF
+   b. Prepare the OAuth2 variables for authenticate information.
+
+      When using JWT with Shared Key, the following attributes need to be
+      configured. Here's an example for preparation:
 
-         kubectl apply -f smo-secret.yaml
+      ::
+      
+         OAUTH2_ALGORITHM=RS256
+         OAUTH2_PUB_KEY=<3rd-party OAuth Server Public Key>
 
-         export SMO_TOKEN_DATA=$(kubectl get secrets $SMO_SECRET -o jsonpath='{.data.token}' | base64 -d -w 0)
+      For Token Introspection, here are examples of the required preparation:
 
-   3. Create certificates for the O2 service.
+      ::
+      
+         OAUTH2_INTROSPECTION_ENDPOINT=http://<3rd-party OAuth Server Address>:8080/realms/master/protocol/openid-connect/token/introspect
+         OAUTH2_CLIENT_ID=<oran-o2-client-id>
+         OAUTH2_CLIENT_SECRET=<oran-o2-client-secret>
+
+   c. Create certificates for the O2 service.
 
       Obtain an intermediate or Root CA-signed certificate and key from
       a trusted intermediate or Root Certificate Authority (CA). Refer
@@ -190,7 +178,7 @@ You can install O-RAN O2 application on INF from the command line.
          shared with the SMO application for the O2 server certificate
          verification.
 
-   4. Prepare the O2 service application configuration file.
+   d. Prepare the O2 service application configuration file.
 
       As per the Cloudification and Orchestration use case defined in
       O-RAN Working Group 6, the following information should be
@@ -212,7 +200,6 @@ You can install O-RAN O2 application on INF from the command line.
 
          ocloud_global_id = ${OCLOUD_GLOBAL_ID}
          smo_register_url = ${SMO_REGISTER_URL}
-         smo_token_data = ${SMO_TOKEN_DATA}
 
          [OCLOUD]
          OS_AUTH_URL = ${OS_AUTH_URL}
@@ -220,6 +207,17 @@ You can install O-RAN O2 application on INF from the command line.
          OS_PASSWORD = ${OS_PASSWORD}
          API_HOST_EXTERNAL_FLOATING = ${API_HOST_EXTERNAL_FLOATING}
 
+         [OAUTH2]
+         oauth2_verify_type = jwt
+         oauth2_public_key = ${OAUTH2_PUB_KEY}
+         oauth2_algorithm = ${OAUTH2_ALGORITHM}
+
+         # required if oauth2_verify_type = introspection
+         #oauth2_verify_type = introspection
+         #oauth2_introspection_endpoint = ${OAUTH2_INTROSPECTION_ENDPOINT}
+         #oauth2_client_id = ${OAUTH2_CLIENT_ID}
+         #oauth2_client_secret = ${OAUTH2_CLIENT_SECRET}
+
          [API]
 
          [WATCHER]
@@ -227,7 +225,7 @@ You can install O-RAN O2 application on INF from the command line.
          [PUBSUB]
          EOF
 
-   5. Retrieve the CA certificate from your SMO vendor.
+   e. Retrieve the CA certificate from your SMO vendor.
 
       If the SMO application provides service via HTTPS, and the server
       certificate is self-signed, the CA certficate should be retrieved
@@ -236,7 +234,21 @@ You can install O-RAN O2 application on INF from the command line.
       This procedure assumes that the name of the certificate is
       ``smo-ca.pem``
 
-   6. Populate the override yaml file.
+   f. Prepare client certificate for mTLS (Mutual TLS).
+
+      When you request the O2 application from SMO, it needs the
+      certificate for mTLS.
+      We assume you have the CA certificate and CA key of the SMO
+      client, you can follow the guide to generate the client
+      certficate.
+
+      ::
+
+         openssl genrsa -out client-key.pem 2048
+         openssl req -new -key client-key.pem -out client.csr
+         openssl x509 -req -in client.csr -CA smo-ca.pem -CAkey smo-ca-key.pem -CAcreateserial -out client-cert.pem -days 365
+
+   j. Populate the override yaml file.
 
       Refer to the previous step for the required override values.
 
@@ -288,6 +300,7 @@ You can install O-RAN O2 application on INF from the command line.
                   redis: ${O2SERVICE_IMAGE_REG}/docker.io/library/redis:alpine
                 pullPolicy: IfNotPresent
               logginglevel: "DEBUG"
+              useHostCert: true
 
             applicationconfig: ${APPLICATION_CONFIG}
             servercrt: ${SERVER_CERT}
index 5b173c9..46fe99e 100644 (file)
@@ -1,6 +1,6 @@
 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
 .. SPDX-License-Identifier: CC-BY-4.0
-.. Copyright (C) 2021-2022 Wind River Systems, Inc.
+.. Copyright (C) 2021-2024 Wind River Systems, Inc.
 
 INF O2 Service User Guide
 =========================
@@ -9,12 +9,35 @@ This guide will introduce the process that make INF O2 interface work
 with SMO.
 
 -  Assume you have an O2 service with INF platform environment, and you
-   have the token of the O2 service.
+   have the OAuth Server configured with the O2 service.
 
    .. code:: bash
 
       export OAM_IP=<INF_OAM_IP>
-      export SMO_TOKEN_DATA=<TOKEN of O2 Service>
+
+      export OAUTH2_TOKEN_ENDPOINT=http://<3rd-party OAuth Server Address>:8080/realms/master/protocol/openid-connect/token
+      export OAUTH2_CLIENT_ID=<oran-o2-client-id>
+      export OAUTH2_CLIENT_SECRET=<oran-o2-client-secret>
+
+   Get berar token from the OAuth Server for request O2 application API.
+
+   .. code:: shell
+
+      curl -k -X POST ${OAUTH2_TOKEN_ENDPOINT} \
+         -H "Content-Type: application/x-www-form-urlencoded" \
+         -d "grant_type=client_credentials" \
+         -d "client_id=${OAUTH2_CLIENT_ID}" \
+         -d "client_secret=${OAUTH2_CLIENT_SECRET}"
+
+   Set "access_token" value from the above step to the bash environment.
+   And copy the client certificate into the bash folder that you are working on.
+
+   .. code:: bash
+
+      export BEARER_TOKEN=<access_token>
+
+      ls
+      client-cert.pem  client-key.pem  my-root-ca-cert.pem 
 
 -  Discover INF platform inventory
 
@@ -28,9 +51,12 @@ with SMO.
 
       .. code:: shell
 
-         curl -k -X 'GET' \
-           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/" \
-           -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}"
+         curl -X 'GET' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
+           -H 'accept: application/json'
+           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/"
 
    -  Resource pool
 
@@ -44,12 +70,15 @@ with SMO.
 
       .. code:: shell
 
-         curl -k -X 'GET' \
-           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools" \
-           -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}"
+         curl -X 'GET' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
+           -H 'accept: application/json'
+           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools"
 
          # export the first resource pool id
-         export resourcePoolId=`curl -k -X 'GET' "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools"   -H 'accept: application/json' -H "Authorization: Bearer $SMO_TOKEN_DATA" 2>/dev/null | jq .[0].resourcePoolId | xargs echo`
+         export resourcePoolId=`curl -k -X 'GET' --cert client-cert.pem --key client-key.pem "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools"   -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | jq .[0].resourcePoolId | xargs echo`
 
          echo ${resourcePoolId} # check the exported resource pool id
 
@@ -62,9 +91,12 @@ with SMO.
 
       .. code:: shell
 
-         curl -k -X 'GET' \
-           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourceTypes" \
-           -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}"
+         curl -X 'GET' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
+           -H 'accept: application/json'
+           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourceTypes"
 
    -  Resource
 
@@ -73,9 +105,12 @@ with SMO.
 
       .. code:: shell
 
-         curl -k -X 'GET' \
-         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools/${resourcePoolId}/resources" \
-         -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}"
+         curl -X 'GET' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
+           -H 'accept: application/json'
+         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools/${resourcePoolId}/resources"
 
       To get the detail of one resource, need to export one specific
       resource id that wants to check
@@ -83,7 +118,7 @@ with SMO.
       .. code:: shell
 
          # export the first resource id in the resource pool
-         export resourceId=`curl -k -X 'GET' "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools/${resourcePoolId}/resources"   -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" 2>/dev/null | jq .[0].resourceId | xargs echo`
+         export resourceId=`curl -k -X 'GET' --cert client-cert.pem --key client-key.pem "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/resourcePools/${resourcePoolId}/resources"   -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" 2>/dev/null | jq .[0].resourceId | xargs echo`
 
          echo ${resourceId} # check the exported resource id
 
@@ -99,9 +134,12 @@ with SMO.
 
       .. code:: shell
 
-         curl -k -X 'GET' \
-           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers" \
-           -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}"
+         curl -X 'GET' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
+           -H 'accept: application/json'
+           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers"
 
 -  Provisioning INF platform with SMO endpoint configuration
 
@@ -139,11 +177,13 @@ with SMO.
          export SMO_SUBSCRIBE_CALLBACK=<The Callback URL for SMO Subscribe resource>
          export SMO_CONSUMER_SUBSCRIPTION_ID=<The Subscription ID of the SMO Consumer>
 
-         curl -k -X 'POST' \
-           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/subscriptions" \
+         curl -X 'POST' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
            -H 'accept: application/json' \
            -H 'Content-Type: application/json' \
-           -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+           "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/subscriptions" \
            -d '{
            "callback": "'${SMO_SUBSCRIBE_CALLBACK}'",
            "consumerSubscriptionId": "'${SMO_CONSUMER_SUBSCRIPTION_ID}'",
@@ -168,11 +208,13 @@ with SMO.
          export SMO_SUBSCRIBE_CALLBACK=<The Callback URL for SMO Subscribe alarm>
          export SMO_CONSUMER_SUBSCRIPTION_ID=<The Subscription ID of the SMO Consumer>
 
-         curl -k -X 'POST' \
-           "https://${OAM_IP}:30205/o2ims-infrastructureMonitoring/v1/alarmSubscriptions" \
+         curl -X 'POST' \
+           --cacert my-root-ca-cert.pem \
+           --cert client-cert.pem --key client-key.pem \
+           -H "Authorization: Bearer ${BEARER_TOKEN}" \
            -H 'accept: application/json' \
            -H 'Content-Type: application/json' \
-           -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+           "https://${OAM_IP}:30205/o2ims-infrastructureMonitoring/v1/alarmSubscriptions" \
            -d '{
            "callback": "'${SMO_SUBSCRIBE_CALLBACK}'",
            "consumerSubscriptionId": "'${SMO_CONSUMER_SUBSCRIPTION_ID}'",
@@ -216,16 +258,16 @@ with SMO.
    .. code:: bash
 
       # Get all DMS ID, and print them with command
-      dmsIDs=$(curl -k -s -X 'GET' \
+      dmsIDs=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
       "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers" \
-      -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+      -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
       | jq --raw-output '.[]["deploymentManagerId"]')
       for i in $dmsIDs;do echo ${i};done;
 
       # Choose one DMS and set it to bash environment, here I set the first one
-      export dmsID=$(curl -k -s -X 'GET' \
+      export dmsID=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers" \
-        -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+        -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
         | jq --raw-output '.[0]["deploymentManagerId"]')
 
       echo ${dmsID} # check the exported DMS Id
@@ -241,26 +283,26 @@ with SMO.
 
       CLUSTER_NAME="o2dmsk8s1" # set the cluster name
 
-      K8S_SERVER=$(curl -k -s -X 'GET' \
+      K8S_SERVER=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers/${dmsID}?profile=native_k8sapi" \
-        -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+        -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
         | jq --raw-output '.["extensions"]["profileData"]["cluster_api_endpoint"]')
-      K8S_CA_DATA=$(curl -k -s -X 'GET' \
+      K8S_CA_DATA=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers/${dmsID}?profile=native_k8sapi" \
-        -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+        -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
         | jq --raw-output '.["extensions"]["profileData"]["cluster_ca_cert"]')
 
-      K8S_USER_NAME=$(curl -k -s -X 'GET' \
+      K8S_USER_NAME=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers/${dmsID}?profile=native_k8sapi" \
-        -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+        -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
         | jq --raw-output '.["extensions"]["profileData"]["admin_user"]')
-      K8S_USER_CLIENT_CERT_DATA=$(curl -k -s -X 'GET' \
+      K8S_USER_CLIENT_CERT_DATA=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers/${dmsID}?profile=native_k8sapi" \
-        -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+        -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
         | jq --raw-output '.["extensions"]["profileData"]["admin_client_cert"]')
-      K8S_USER_CLIENT_KEY_DATA=$(curl -k -s -X 'GET' \
+      K8S_USER_CLIENT_KEY_DATA=$(curl -k -s -X 'GET' --cert client-cert.pem --key client-key.pem \
         "https://${OAM_IP}:30205/o2ims-infrastructureInventory/v1/deploymentManagers/${dmsID}?profile=native_k8sapi" \
-        -H 'accept: application/json' -H "Authorization: Bearer ${SMO_TOKEN_DATA}" \
+        -H 'accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" \
         | jq --raw-output '.["extensions"]["profileData"]["admin_client_key"]')
 
       # If you do not want to set up the CA data, you can execute following command without the secure checking