VPN Service Underlay Change Processor: Monitor SR Policy Changes and Associating VPN Services in CNC
This example shows step-by-step NB API calls to monitor service underlay transport changes and identify affected VPN services, enabling OSS/BSS/HCO systems to update service-to-transport associations in CNC.
The scenario demonstrates the following steps:
- Subscribe to SR-policy change notifications to monitor service underlay transport changes.
- Process the SSE data stream and assemble it into event data.
- Invoke a function that processes the event data according to the event model.
- Conditionally process events to identify SR-policy creation events.
- Retrieve the VPN services that are associated with the created SR-policy.
This example uses the operations from the following API references.
- SR Policy Change Notification Subscription API: Subscribes to notifications about SR-policy changes.
- Transport to Service Mapping Retrieval API: Retrieves VPN services that are associated with transport policies.
- Device Inventory Query API: Queries device inventory to map router IDs to NSO nodes.
Prerequisites
Before running the examples, ensure that the following prerequisites are met:
- Day-0 device configurations are completed on all devices.
- Set up the device topology correctly in the CNC cluster.
- If your topology or data differs from the example input, adjust the input data accordingly. Refer to the CNC installation guide and administration guide for details on configuring day-0 devices and topology.
Process Service Underlay Change Events
To run this example end-to-end, execute two scripts in separate terminals.
- Step 1: In first terminal, Run the script service-underlay-change-processor.sh from the example directory to subscribe to service state change notifications, process the event, and retrieve the service config intent on the change completion.
- Step 2: In second terminal, Run the script create-l3vpn-with-odn.sh to observe the service state change events processing in the first terminal.
Note: Remove the L3VPN service with ODN before recreating it to ensure that the system generates and processes SR-policy change events in this example.
cd ~/cnc-api-examples/service-underlay-transport;./service-underlay-change-processor-sr-te.sh
cd ~/cnc-api-examples/l3vpn-with-odn;./create-l3vpn-with-odn.sh
The script execution outputs the API execution and results to standard output and store the results in multiple files in output folder.
Input
The script requires the following input files in the input directory: ~/cnc-api-examples/service-underlay-transport/input
- sr-policy-change-event-stream-create-input.json
- get-associated-services-for-sr-policy-input-template.json
- node-query-input-template.json
Note: Files with the -template suffix in the input directory serve as templates with variables to generate final input files in the work directory for script use.
Output
The script creates the following output files in the output directory during and after its execution: ~/cnc-api-examples/service-underlay-transport/output
- sr-policy-change-event-stream.txt
- get-associated-services-for-sr-policy-output.json
- sr-policy-change-event-stream-create-output.json
- node-query-output.json
Note: During the script execution while subscribing to notifications, the stream adds the received event data to the
sr-policy-change-event-stream.txt
file. To continuously monitor all events from the stream, use the tail command on the file in a separate terminal.tail -F ~/cnc-api-examples/service-underlay-transport/output/sr-policy-change-event-stream.txt
Script Details : service-underlay-change-processor-sr-te.sh
#!/bin/bash
#
# Usecase:
# This example scenario demonstrates step by step NB API invocation with the required input
# to subscribe, receive, process notifications to monitior service underlay transport changes
# and identify the associated VPN services for the transport that is changed in CNC.
# Any OSS/BSS/HCO sytems that monitors the changes in the underlay transport to update the
# associated VPN services collected from CNC can use these APIs to track the changes in CNC to
# process the vpn service to transport associations.
#
# The scenario demonstrates
# Step 1: Subscribing to SR-policy change notifications to monitor service underlay transport changes.
# Step 2: Process the SSE data stream to assembly it into a event data.
# Step 3: Invoke a function that process event data according to event model.
# Step 4: Conditionally process the event to identify which event indicates a sr-policy creation.
# Step 5: Retreive the VPN services associated with the SR-policy that was created.
export PRJ=$(cd `dirname $0`; pwd)
. $PRJ/../common-scripts/env
. $PRJ/../common-scripts/cnc-api-common.sh
# Gets the nso node id used in the vpn service intent given a router id of the device.
# $1 routerId, return nso node id mapped between CNC and NSO
routerId2NsoNodeId() {
nodeRouterId="$1"
# prepare the DLM query input
nodeQueryInput=$(cat $PRJ/input/node-query-input-template.json);
nodeQueryInput=${nodeQueryInput/"V_ROUTER_ID"/$nodeRouterId}
echo "$nodeQueryInput" > $PRJ/work/node-query-input.json
# invoke the DLM query API to get the device details
export_rest_headers
CNC_API_URL=https://$CNC_HOST:$CNC_PORT/crosswork/inventory/v1/nodes/query
CNC_API_INPUT=$PRJ/work/node-query-input.json
CNC_API_OUTPUT=$PRJ/output/node-query-output.json
http_post $CNC_API_URL $CNC_API_INPUT $CNC_API_OUTPUT
# process the DLM query output to get the nso node id of this device
nodeInfo=$(cat $PRJ/output/node-query-output.json)
nsoNodeId=$(jq -r '."data".[0]."providers_family"."ROBOT_PROVIDER_NSO"."providers"[]."provider_node_id"' <<< "$nodeInfo")
# export the NSO_NODE_ID to use it in the caller funtion
NSO_NODE_ID="$nsoNodeId"
export NSO_NODE_ID
}
# Gets the associated vpn services for a given SR policy
# $1 headend(routerId), $2 endpoint(routerId), $3 color from the SR policy change notifications
get-associated-services-for-sr-policy() {
srpHeadend="$1"
srpEndpoint="$2"
srpColor="$3"
echo ""
echo "Retrieving the services associated with the discovered policy:=[$srpHeadend,$srpEndpoint,$srpColor]"
echo ""
# get nso node id for the head end
routerId2NsoNodeId "$srpHeadend"
srpHeadendNsoNodeId="$NSO_NODE_ID";
# build the get associated services for transport request for the sr-policy
svcForSrPolicyReq=$(cat $PRJ/input/get-associated-services-for-sr-policy-input-template.json);
svcForSrPolicyReq=${svcForSrPolicyReq/"V_HEAD_END"/$srpHeadendNsoNodeId}
svcForSrPolicyReq=${svcForSrPolicyReq/"V_COLOR"/$srpColor}
svcForSrPolicyReq=${svcForSrPolicyReq/"V_ENDPOINT"/$srpEndpoint}
echo $svcForSrPolicyReq > $PRJ/work/get-associated-services-for-sr-policy-input.json
# invoke get associated services for transport policy api
export_restconf_headers
CNC_API_URL=$CNC_CAT_RESTCONF_CTX/operations/cat-inventory-rpc:get-associated-services-for-transport
CNC_API_INPUT=$PRJ/work/get-associated-services-for-sr-policy-input.json
CNC_API_OUTPUT=$PRJ/output/get-associated-services-for-sr-policy-output.json
http_post $CNC_API_URL $CNC_API_INPUT $CNC_API_OUTPUT
echo ""
# TODO: extract the service paths from the response and retrieve the service intents and oper data.
}
# Process the sr-policy change event according to the model.
# $1 rcEvent: event data as a whole that is assembled from notification stream
process-sr-policy-change-event() {
local rcEvent="$1"
# process and extract the event specific data - extract headend, color, endpoint and event type
eHeadend=$(jq -r '."ietf-restconf:notification"."cisco-crosswork-segment-routing-policy:sr-policy-change-event"."policy"."headend"' <<< "$rcEvent")
eColor=$(jq -r '."ietf-restconf:notification"."cisco-crosswork-segment-routing-policy:sr-policy-change-event"."policy"."color"' <<< "$rcEvent")
eEndpoint=$(jq -r '."ietf-restconf:notification"."cisco-crosswork-segment-routing-policy:sr-policy-change-event"."policy"."endpoint"' <<< "$rcEvent")
eType=$(jq -r '."ietf-restconf:notification"."cisco-crosswork-segment-routing-policy:sr-policy-change-event"."change-type"' <<< "$rcEvent")
# log all events
echo "$rcEvent" >> $PRJ/output/sr-policy-change-event-stream.txt
# on receiving the event that indicates sr-policy created, call a function to retrieve the associated vpn-services
if [[ "$eType" == "POLICY-CREATE" ]]; then
# process only create event
get-associated-services-for-sr-policy "$eHeadend" "$eEndpoint" "$eColor"
fi
}
# Subscribe to sr-policy change notifications stream to assemble the stream data
# into a sequence of events and call a process event function to process the event data
subcribe-and-process-sr-policy-change-event-notif() {
echo "Subscribing and Processing sr policy change events..."
# Subscribing to the SR policy change event notifications is a two-step process
# First, create the stream subscription id (uuid)
# then use it to subscribe the stream to received the notifications
export CNC_API_URL="$CNC_TOPOLOGY_RESTCONF_CTX/operations/sal-remote:create-notification-stream"
CNC_API_INPUT="$PRJ/input/sr-policy-change-event-stream-create-input.json"
CNC_API_OUTPUT="$PRJ/output/sr-policy-change-event-stream-create-output.json"
http_post $CNC_API_URL $CNC_API_INPUT $CNC_API_OUTPUT
# extract the stream id (UUID) from the create response
local srStreamCreateOutput=$(cat $PRJ/output/sr-policy-change-event-stream-create-output.json)
SR_POLICY_CHANGE_EVENT_STREAM_UUID=$(jq -r '."sal-remote:output"."notification-stream-identifier"' <<< "$srStreamCreateOutput")
echo ""
echo "STREAM UUID : $SR_POLICY_CHANGE_EVENT_STREAM_UUID"
echo ""
# Subscribe and receve the stream data to assemble the data into event data and invoke the event processing function
export CNC_API_URL="$CNC_TOPOLOGY_RESTCONF_CTX/streams/json/$SR_POLICY_CHANGE_EVENT_STREAM_UUID"
export RC_EVENT
echo "Subscribing to the sr policy change events stream... $CNC_API_URL"
while true; do
curl $CURL_OPTS -N -X GET $CNC_API_URL -H 'Accept: text/event-stream' -H "$AUTH_TOKEN_HDR" | while read -r line; do
if [[ "$line" == "data:"* ]]; then
data=$(echo "$line" | sed 's/^data: //')
# Append the event data until new empty line
RC_EVENT+="$data"$'\n'
elif [[ "$line" == ": ping"* ]]; then
# heart beat. ignore
ping="$line"
elif [[ -z "$line" ]]; then
# Received empty line indicating end of event data or ping
# Process the event data and reset event data
if [[ -n "$RC_EVENT" ]]; then
# echo "$RC_EVENT"
process-sr-policy-change-event "$RC_EVENT"
RC_EVENT=""
fi
else
echo "Received unknown data:: $line"
fi
done
sleep 0.1 # Optional: add a small delay to prevent excessive CPU usage
done
}
main() {
# Assume CNC JWT has been obtained prior to invoking this method by executing get-cnc-jwt.sh script
# Read from JWT file and export it as AUTH_TOKEN_HDR
export_jwt
# Subscribe and process SR policy change events to understand which VPN services are associated with the event for further processing.
subcribe-and-process-sr-policy-change-event-notif
}
main