Accessing Provider Connective Assurance with gNMI
  • 27 Feb 2025
  • 12 Minutes to read
  • Contributors
  • PDF

Accessing Provider Connective Assurance with gNMI

  • PDF

Article summary

The Cisco Provider Connectivity Assurance solution supports gNMI for data queries and export, allowing for seamless integration with both Cisco and non-Cisco telemetry data. This solution enables proactive assurance of business-critical networks, services, and applications through synthetic network and service testing, user experience monitoring, and AI-powered issue detection.

Accessing the Provider Connectivity Assurance platform using gNMI gNMI enhances network visibility, reliability, and operational efficiency, ensuring secure access with multiple authentication methods, which protects sensitive data. It also enables automation, increasing efficiency and reducing errors.

For details about the Provider Connectivity Assurance Solution, see: Provider Connectivity Assurance Solution

This article will help you understand how to authenticate and use gNMI (gRPC Network Management Interface) with Provider Connective Assurance to optimize your network management and monitoring.

Getting Started: Authentication

Provider Connective Assurance supports the following three authentication methods:
• Credentials: Use your Provider Connective Assurance login details.
• JWT (JSON Web Token): A long-lived token created via the Provider Connectivity Assurance API.
• Bearer Token: A short-lived token obtained from the Provider Connectivity Assurance login.

Using Credentials

You can connect to gNMI using your Provider Connective Assurance username and password. Here's some example commands using gnmic, a gNMI client:

gnmic

gnmic  -a cisco-cnc.dhuscisco-dev.analytics.accedian.io:443 --format protojson  -u admin@datahub.com -p <passwd> subscribe --path '/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics' --mode stream

gnmi_cli (Openconfig reference implementation)

gnmi_cli  -a cisco-cnc.dhuscisco-dev.analytics.accedian.io:443 -tls_skip_verify  -display_type p -query_type s -t '/gnmi.gNMI/' -q /object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics -with_per_rpc_auth -with_user_pass

💡Queries for username and password

gnmicli

Accedian flavoured version of openconfig gnmi client, supports JWT and Baerer Auth (see below)

gnmicli --addr cisco-cnc.dhuscisco-dev.analytics.accedian.io:443 --auth credentials --username admin@datahub.com --password <password> --insecureTls --query /accedian:session/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics

JWT

Authentication is done using a long lived JWT (JSON Web Token). The JWT is created via corresponding Provider Connectivity Assurance API. When a gNMI subscription request is issued, the JWT has to be included in the gRPC metadata under the Authorization key.

  1. Login to Provider Connectivity Assurance as tenant-admin
  2. Issue request to {{baseUrl}}/api/v1/auth/tokens
{
    "data": {
        "attributes" : {
            "aud": "accedian",
            "iss": "accedian",
            "sub": "user@datahub.com",
            "tenantURL": "{{baseUrl}}",
            "exp" : 35683279714
        },
        "type": "tokens"
    }
}
  1. Copy the create JWT

    eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhY2NlZGlhbiIsInN1YiI6ImFkbWluQGRhdGFodWIuY29tIiwiZXhdwIjozNTY4MzI3OTcxNCwtilXVkIjoiYWNjZWRpYW4iLCJ0b2tlbklEIjoyOTIsInRlbmFudElEIjoiZTE5MTYwYjctMTBrararlZC00YmZiLTlkZDctMjYwMjM0NTQ5NzgzIiwidGVuYW50VVJMIjoiaHR0cHM6Ly90rZW5hbnQxLmJlcGVyZi5ucGD2LmFjY2VkaWFuLm5ldCJ9.cKmhYJbYBjSrsf9l-NlzuQ8781chGUjTnhfRzclQ2IY
    
  2. Add to gRPC metadata with key: Authorization

💡The Accedian gNMI client supports the JWT auth ($AUTH_TOKEN is a JWT token string)

Example:

./gnmicli --addr cisco-cnc.dhuscisco-dev.analytics.accedian.io:443  --query /object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics/jitter-p95 --auth token --insecureTls --authToken $AUTH_TOKEN

Bearer Token

You can also use the Bearer token returned by the Provider Connectivity Assurance login and add that to the gRPC metadata Authorization header. Note however, that these tokens are short lived.

Bearer MTY2ODQzNzI0MHxkRFlFSmQ5Y3JUak9heEg1amRIMUNPSl9yYmdmMkZORm5pOU1IY3d3YXc1Vk1PbUVteFctbS1ZaW9TTTlHcEdMUy1UNnE5QVNIV2F1aXVqZVZzbl85eWhlczlqOW5PWTBrQ09nMDdacEhrMjZIN1dHcU50RVRoZ2pRMklxV0p4d1jdsbmRfcHRMdmcxYm5YUndCNlNpZU5zalltTVZ0bkhTU2hZUG9qc0p5RUVTZXpQeUd1UUx6OTBJd0c0dFNiVDA5RVRKVHZzcUtMZFB2UWQ5cldaMVVUTm5IZ1hXUmRsN0EtNWJfajZMdkItMmFpMW9rY3V5UmV0N2c0Qk0pPV1l4UFBacG1objdTVi15cENPU3R2Q2x6YWxWNDJSRUxQS3NzZHlZajhmTkJPb250TGxVZ1V6aXBmSTVURDVQM1VDMG1JblVGT3JDak1rUHA2NkV1U3ZqZWY1VkdZaDlMTzlweTlalalalQZEFrVVM1TWQ1dTYwODBmaW5XN3VrQ1pONURLNHMzV2VWWWJOTktxME0yNUl5RlNFSncxR0wzUlVxcXFhbFAtOVViR1pjNW82T1pham9PUDcwLXdmM0V3SnZHdThQYnJ3d0d4RGZOUkF1bHpWZHMtSEFqM1JURFM2Wmt1US1DRjM5NDZGc1ZKSlRjeWtaQWJReTd6Nmk3NF9BanNPSUlZREQ3TEt2WnpLbXp0YXNoSnJlQjVHQkkzQ3RHUGZaTnZPeEg2RFR5bWhqZlpueGJGRWRlV1VmeE5vblJCbWtzMlMwbXplSm80N3FwRWJibkN6TTdWUS1nekx1cjRwa3UyN0p4SXJNanJld0NES1EzMzI4OHg1Q25XNDZrRXdlMzFEaF9xcHZ2WFhUaW9ZRTZEaVBRSmlnc19hVlhKT3lBZkJQVXhSZW9TdkZZMUdxSHA0bWw5ZXVhV0tMOHZWXzNJR1V5dXpBYzh3cGFLVTdBa0xvYnJkNjhQcHJEQkRja3p3aGl1S3RwaFZBUmNYYmRTNTVuQXRnR2FoRmVnQ3ZVNk9qWVdTTVc0T2xleFltYVVneldMZmdIUjFXdlRyS2p1LTFuN2tUSUd5aEljd2ptUzRfMzBVZWZEendJY3plZTh1enJiLTF6VUhqRmszYjN4LTdzT3VTWnpiU0ZjOVpzSTl2WTNvZmsyZy1yRmlXOEp1Rnz4yMZO3BDMzI3V6JIspPYE3rKqs0P7I0Y9NQVFXukNkQ==

💡The Accedian gNMI client supports Bearer token auth ($AUTH_TOKEN is a Bearer token string, without the prefix: Bearer)

./gnmicli --addr cisco-cnc.dhuscisco-dev.analytics.accedian.io:443  --query /object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics/jitter-p95 --auth token --insecureTls --authToken $AUTH_TOKEN

Subscriptions

Subscriptions currently only support STREAM in ON_CHANGE mode. Whenever a session reports new values, it is considered a CHANGE, even if the value did not change since the last report. When a subscription is established, session data is transferred starting from that point in time. Synchronization is currently not implemented, meaning that no session data that was received prior to the subscription, is transferred over the gNMI.

Subscription Paths:

The primary subscription paths are:
• All data available about the session
• Session metrics only
• Specific session metrics

All metrics and metadata

/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]

All metrics

/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics

All metrics with multiple values for category

/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east|europe-west]/metrics

All metrics with multiple categories

/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east;meta/data/name/service=abc]/metrics

Specific metric (leaf)

/object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics/jitter-p95

Reporting Interval

The gNMI interface delivers data in real-time as it is received, because the Provider Connectivity Assurance-streamer is designed to operate without maintaining any state. Consequently, you cannot set a specific reporting interval when you subscribe.

As a result, the data is reported at approximately the same intervals as the session reports its data. For instance, if a subscribed session reports every 30 seconds, you will receive updates approximately every 30 seconds.

YANG model

The following YANG model defines the structure for monitored objects in the Cisco Provider Connectivity Assurance solution. This model specifies the containers and groupings necessary for effective network data management, focusing on metrics and metadata essential for network assurance.

    
    yang-version "1";
    namespace "http://accedian.com/ns/yang/session";

    prefix "accedian";

    organization "Accedian";

    description
        "This YANG module contains the monitored object definition";
    
    revision 2022-10-18 {
        description
            "Network Direction Update";
        reference "1.1.0";
    }

    container object-type {
        description "Monitored Object type";
        config false;
        container twamp-sf {
            container monitored-objects {
                list monitored-object {
                    key "monitored-object-id monitored-object-name direction service-id";
                    uses properties-grouping; 
                    container location {
                        container source-location {
                            uses location-grouping;
                        }
                        container destination-location {
                            uses location-grouping;
                        }
                    }
                    container metrics {
                        uses metrics-grouping;
                    }
                    container meta {
                        uses meta-grouping;
                    }
                }
            }
        }
    }

    grouping properties-grouping {
        leaf monitored-object-id {
            type string;
            description "Monitored Object unique identifier";
        }
        leaf session-id {
            type string;
            description "Session ID";
        }
        leaf monitored-object-name {
            type string;
            description "Monitored object name";
        }
        leaf direction {
            type network-direction;
            description "Direction";
        }  
        leaf-list Topology {
            type string;
            description "Topology";
        }
        leaf service-id {
            type string;
            description "Service ID";
        }
    }

    grouping metrics-grouping {
        leaf bytes-received {
            type decimal64 {
                fraction-digits 5;
            }
            description "Bytes Received";
        }
        leaf delay-avg {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay average";
        }
        leaf sync-quality {
            type int64;
            description "sync quality";
        }
        leaf sync-state {
            type int64;
            description "sync state";
        }
        leaf delay-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay max";
        }
        leaf delay-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay min";
        }
        leaf delay-p25 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay p25";
        }
        leaf delay-p50 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay P50";
        }
        leaf delay-p75 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay P75";
        }
        leaf delay-p95 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay P95";
        }
        leaf delay-phi {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay PHi";
        }
        leaf delay-plo {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay PLo";
        }
        leaf delay-pmi {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay PMi";
        }
        leaf delay-std-dev-avg {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay standard deviation average";
        }
        leaf delay-var-avg {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var avg";
        }
        leaf delay-var-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var max";
        }
        leaf delay-var-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var min";
        }
        leaf delay-var-p25 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var P25";
        }
        leaf delay-var-p50 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var P50";
        }
        leaf delay-var-p75 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var P75";
        }
        leaf delay-var-p95 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var P95";
        }
        leaf delay-var-phi {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var PHi";
        }
        leaf delay-var-plo {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var PLo";
        }
        leaf delay-var-pmi {
            type decimal64 {
                fraction-digits 5;
            }
            description "Delay var PMi";
        }
        leaf duration {
            type decimal64 {
                fraction-digits 5;
            }
            description "Duration";
        }
        leaf ip-tos-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "IP TOS Max";
        }
        leaf ip-tos-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "IP TOS Min";
        }
        leaf jitter-avg {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter Average";
        }
        leaf jitter-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter Max";
        }
        leaf jitter-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter Min";
        }
        leaf jitter-p25 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter P25";
        }
        leaf jitter-p50 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter P50";
        }
        leaf jitter-p75 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter P75";
        }
        leaf jitter-p95 {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter P95";
        }
        leaf jitter-phi {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter PHi";
        }
        leaf jitter-plo {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter PLo";
        }
        leaf jitter-pmi {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter PMi";
        }
        leaf jitter-std-dev {
            type decimal64 {
                fraction-digits 5;
            }
            description "Jitter Std Dev";
        }
        leaf lost-burst-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "Lost Burst Max";
        }
        leaf lost-burst-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "Lost burst min";
        }
        leaf mos {
            type decimal64 {
                fraction-digits 5;
            }
            description "MOS";
        }
        leaf packets-lost {
            type decimal64 {
                fraction-digits 5;
            }
            description "Packets lost";
        }
        leaf packets-lost-pct {
            type decimal64 {
                fraction-digits 5;
            }
            description "Packets lost pct";
        }
        leaf packets-duplicated {
            type decimal64 {
                fraction-digits 5;
            }
            description "Packets duplicated";
        }
        leaf packets-misordered {
            type decimal64 {
                fraction-digits 5;
            }
            description "Packets misordered";
        }
        leaf packets-received {
            type decimal64 {
                fraction-digits 5;
            }
            description "Packets received";
        }
        leaf packets-too-late {
            type decimal64 {
                fraction-digits 5;
            }
            description "Packets too late";
        }
        leaf periods-lost {
            type decimal64 {
                fraction-digits 5;
            }
            description "Periods lost";
        }
        leaf rvalue {
            type decimal64 {
                fraction-digits 5;
            }
            description "RValue";
        }
        leaf ttl-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "TTL Max";
        }
        leaf ttl-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "TTL Min";
        }
        leaf vlan-pbit-min {
            type decimal64 {
                fraction-digits 5;
            }
            description "VLAN PBit Min";
        }
        leaf vlan-pbit-max {
            type decimal64 {
                fraction-digits 5;
            }
            description "VLAN PBit Max";
        }
    }
    grouping location-grouping {
        leaf lat {
            type decimal64 {
                fraction-digits 7;
            }
            description "latitude";
        }
        leaf lon {
            type decimal64 {
                fraction-digits 7;
            }
            description "longitude";
        }
        
    }

   grouping meta-grouping {
        list data {
            key name;
            leaf name {
                type string;
            }
            leaf val {
                type string;
            }
        }
    }

    typedef network-direction {
        type enumeration {
            enum -1 {
                description
                    "NON: No Direction";
            }
            enum 0 {
                description
                    "SD: Source to Destination - metrics with this directionality represents the packet stats seen as they arrive at the destination";
            }
            enum 1 {
                description
                    "DS: Destination to Source - metrics with this directionality represents the packet stats seen starting from the destination back to the source";
            }
            enum 2 {
                description
                    "RT: Round Trip - metrics with this directionality represent the packet stats seen between the source back to itself";
            }
        }
    }

}

Cisco gNMI Client

We provide a test client, based on the openconfig gNMI framework, to connect to the Cisco Provider Connectivity Assurance gNMI and verify data is flowing.

Usage: gnmicli --addr ADDR --query QUERY [--target TARGET] [--tenantId TENANTID] [--auth AUTH] [--authToken AUTHTOKEN] [--insecureTls] [--username USERNAME] [--password PASSWORD]

Options:
  --addr ADDR, -a ADDR   Address of the gNMI server
  --query QUERY, -q QUERY
                         gNMI subscription query path
  --target TARGET        Target of the gNMI endpoint [default: /gnmi.gNMI/]
  --tenantId TENANTID, -t TENANTID
                         Required for NoAuth [--auth none]
  --auth AUTH            Authentication type: [token], [credentials] or [none] [default: none]
  --authToken AUTHTOKEN
                         Token for authentication. Required for [token] authentication
  --insecureTls          Adds insecure TLS (skip verify) [default: false]
  --username USERNAME    Username for credentials auth
  --password PASSWORD    Password for credentials auth
  --help, -h             display this help and exit

Example usage:

./gnmicli --addr cisco-cnc.dhuscisco-dev.analytics.accedian.io:443  --query /object-type/twamp-sf/monitored-objects/monitored-object[meta/data/name/usage=europe-east]/metrics/jitter-p95 --auth token --insecureTls --authToken $AUTH_TOKEN

Postman Setup

This section guides you through setting up Postman to interact with the gNMI interface of the Cisco Provider Connectivity Assurance solution. By following these steps, you can configure Postman to test and verify gNMI queries and subscriptions, enabling efficient network monitoring and data analysis.

  1. Download/Clone gnmi.proto and gnmi_ext.proto from openconfig on github to your local machine.
    https://github.com/openconfig/gnmi/tree/master/proto
  2. In postman by the workspace click “new” and then select gRPC request

image.png

  1. Navigate to the service definition tab of the request, select “Import a .proto file”

image.png

  1. Chose gnmi.proto as the proto file

  2. Add your path to the gnmi_ext.proto file as an import path. Make sure that the postman import path is relative to the import path defined in the gnmi.proto (Which is: github.com/openconfig/gnmi/proto/gnmi_ext/gnmi_ext.proto).
    image.png

  3. Hit “Next”

  4. In “Import as API”, type a name for your API, Provider-Connectivity-Assurance-gNMI for example. Then in the dropdown, select “Create new api” to save your custom name. Finally click the “Import as API” button to save.

  5. Click the lock, to the left of the URL, to enable TLS

  6. Add the server URL to the request (ex. cisco.dhuscisco.analytics.accedian.io/)

  7. Next to the URL, select the gRPC method Subscribe

image.png

  1. Navigate to the Authorization tab of the request, select bearer token as type and then add your token to the appropriate section. The token can be either the JSON Web Token (JWT) you created, or a Bearer token you obtained by logging in to Provider Connectivity Assurance (as in the following screenshot).

image.png

  1. Navigate to the Message tab, add your subscription request
    Ex.

    {
        "subscribe": {
            "mode": "STREAM",
            "prefix": {
                "origin": "accedian:session",
                "elem": [
                    {
                        "name": "object-type"
                    },
                    {
                        "name": "twamp-sf"
                    },
                    {
                        "name": "monitored-objects"
                    }
                ]
            },
            "subscription": [
                {
                   "path": {
                        "origin": "accedian:session",
                        "elem": [
                            {
                                "name": "monitored-object",
                                "key" : {
                                    "meta/data/name/state" : "texas"    
                                }
                            },
                            {
                                "name": "metrics"
                            },
                            {
                                "name": "delay-p75"
                            }
                        ]
                    } 
                },
                {
                   "path": {
                        "elem": [
                            {
                                "name": "monitored-object",
                                "key" : {
                                    "meta/data/name/state" : "colorado"    
                                }
                            },
                            {
                                "name": "metrics"
                            }
                        ]
                    } 
                }
            ]
        }
    }
    
  2. Click the Invoke button to initiate the gRPC stream connection

  3. Click the Send button to pass initiate your subscription streaming

Performance Testing gNMI Server

Performance testing is conducted using a Docker image of our internal gNMI CLI client. You can create custom Docker Compose files to quickly scale gNMI subscriptions with specific metadata filters. During testing, we observed that running more than 100 containers on a single Docker node can be challenging. For over 100 subscriptions, it's advisable to distribute connections across multiple virtual machines. After completing the tests, use docker system prune to clean up the environment efficiently.

Note: The test uses the --perfTesting flag, which implements a NOOP (no operation) for message handling. While this prevents messages from being logged to the console, it enhances server performance.

version: "3.3"

services:
  worker-1:
    image: gcr.io/npav-172917/analytics-streamer:gnmi-cli
    deploy:
      placement:
        constraints:
          - node.labels.oaf == true  
    command: ./gnmicli --perfTesting  --addr ${ADDR} --insecureTls --auth "token" --authToken ${TOKEN} --query ${BASEQUERY}"[meta/data/name/region=east;meta/data/name/source_city=ottawa]/metrics"
  worker-2:
    image: gcr.io/npav-172917/analytics-streamer:gnmi-cli
    deploy:
      placement:
        constraints:
          - node.labels.oaf == true  
    command: ./gnmicli --perfTesting  --addr ${ADDR} --insecureTls --auth "token" --authToken ${TOKEN} --query ${BASEQUERY}"[meta/data/name/region=west]"

Once you configure Docker in swarm mode, ensure that a node in the swarm has the label you set up.

docker node update --label-add oaf=true dnocita1-worker-123

Use the following simple script to stand up the environment with three arguments provided:

./start-test.sh 1 tenant1.beperf.npav.accedian.net:443 $BePerfToken
ArgumentNameDescriptionExample
1DeploymentsThe number of replicas to standup of the compose file, useful to scale connections with minimal subscription configurations1
2AddressgRPC address and port for the tenanttenant1.beperf.npav.accedian.net:443
3TokenAPI token for the tenant, it can be generated by sending a POST call to /api/v1/auth/tokens
#!/bin/bash

if [ $# -eq 0 ]; then
    echo "No arguments provided"
    exit 1
fi

# Varriables
DEPLOYMENTS=$1
ADDR=$2
TOKEN=$3
BASEQUERY="/accedian:session/object-type/twamp-sf/monitored-objects/monitored-object"

# Start files
printf '%.0s\n' {1..3}
echo "~~~ Starting Performance Containers ~~~"
printf '%.0s\n' {1}
for i in $(seq $DEPLOYMENTS)
do
   echo "Starting Performance$i"
   ADDR=$ADDR TOKEN=$TOKEN BASEQUERY=$BASEQUERY docker stack deploy --compose-file performance-docker-compose.yml Performance$i
done

printf '%.0s\n' {1..3}
echo "~~~ Starting Performance Containers Complete ~~~"
printf '%.0s\n' {1}

Use the following script to clean up the environment. Simply provide the same Deployments argument that you used when starting the environment.

./stop-test.sh 1
#!/bin/bash

if [ $# -eq 0 ]; then
    echo "No arguments provided"
    exit 1
fi

# Varriables
DEPLOYMENTS=$1

printf '%.0s\n' {1..3}
echo "~~~ Stopping Previous Performance Containers ~~~"
printf '%.0s\n' {1}
for i in $(seq $DEPLOYMENTS)
do
   echo "Stopping Performance$i"
   docker stack rm Performance$i
done
printf '%.0s\n' {1..3}
echo "~~~ Stopping Previous Performance Containers Complete ~~~"
printf '%.0s\n' {1}

© 2025 Cisco and/or its affiliates. All rights reserved.
 
For more information about trademarks, please visit: Cisco trademarks
For more information about legal terms, please visit: Cisco legal terms

For legal information about Accedian Skylight products, please visit: Accedian legal terms and tradmarks



Was this article helpful?

Changing your password will log you out immediately. Use the new password to log back in.
First name must have atleast 2 characters. Numbers and special characters are not allowed.
Last name must have atleast 1 characters. Numbers and special characters are not allowed.
Enter a valid email
Enter a valid password
Your profile has been successfully updated.
ESC

Eddy AI, facilitating knowledge discovery through conversational intelligence