Examples: Test Agents
Overview of Test Agent Orchestration
Test Agents in Paragon Active Assurance are considered as "configuration" in the context of orchestration. This means that creation, control, and deletion of Test Agents should be done via the orchestrator and NETCONF rather than via the Paragon Active Assurance GUI.
If a Test Agent is installed by a technician and registered to Control Center without first being created via the NETCONF & YANG API, the Test Agent will not exist in the configuration database, and the system will get out of sync. For ConfD to become aware of the Test Agent in this case, it will be necessary to perform a new synchronization with Control Center, as detailed in the section Synchronizing the Configuration Database with Control Center.
Orchestration of Virtual Test Agents (vTAs) should therefore rather be done in the following steps:
- Create the Virtual Test Agent, including its interface configuration, using the NETCONF & YANG interface to Control Center. The name of the Test Agent will be its unique key.
- Deploy the vTA on a virtualization platform. Follow the instructions in
the online help under Test Agents > Installation. The basic interface
configuration that allows the vTA to connect to Control Center, as well as
credentials for authentication, is provided into the vTA using cloud-init user
data. Once the vTA has booted, it will automatically connect to Control Center
using an encrypted OpenVPN connection. A NETCONF notification is sent since the
value of the vTA's test-agent-status-change parameter has now changed to
"online". Note:
Since the name of the vTA is its identifier in Control Center, this name must be the same as that defined in Control Center in step 1.
- Once the vTA has connected and authenticated to Control Center, the interface configuration is pushed to the vTA. This is the interface configuration provided in step 1 when the vTA was created in Control Center.
- After the vTA has served its purpose, delete the vTA.
Creating and Deploying a New Test Agent
We first need to create a Test Agent using the NETCONF & YANG interface to Control Center. When a Test Agent is created in this way, no synchronization with Control Center is needed.
The YANG model for a Test Agent is as depicted below. It is obtained as output from the command
pyang -f tree netrounds-ncc.yang
The full YANG model is given in Appendix: Tree Structure of Full YANG Model, which also contains a legend explaining the conventions used in this and other YANG model illustrations in the present document.
+--rw test-agents | +--rw test-agent* [name] | +--rw name string | +--rw description? string | +--rw tags | | +--rw tag* [name] | | +--rw name -> ../../../../../tags/tag/name | +--ro state | | +--ro status? test-agent-status-t | | +--ro version? string | | +--ro uptime? int64 | | +--ro memory-usage? percent-t | | +--ro load-average | | +--ro last-1-minute? decimal64 | | +--ro last-5-minutes? decimal64 | | +--ro last-15-minutes? decimal64 | +--rw ntp | | +--rw interface? string | | +--rw servers* [address] | | | +--rw address union | | +--rw enable-ipv6? boolean | +--rw management | | +--rw interface? string | | +--rw use-public-address? boolean | +--rw interfaces | | +--rw interface* [name] | | +--rw name string | | +--rw description? string | | +--rw interface-type? interface-type-t | | +--rw mac? yang:mac-address | | +--rw mtu? uint16 | | +--rw speed? speed-t | | +--rw bridge | | | +--rw members | | | +--rw member* [interface] | | | +--rw interface -> ../../../../../interface/name | | +--rw vlan | | | +--rw id vlan-id-t | | | +--rw parent -> ../../../interface/name | | +--rw wifi | | | +--rw ssid? string | | | +--rw bssid? yang:mac-address | | | +--rw country? string | | | +--rw ht boolean | | | +--rw ht40 boolean | | | +--rw vht boolean | | | +--rw sgi boolean | | | +--rw ldpc boolean | | | +--rw ht-mcs? string | | | +--rw vht-max-mcs uint8 | | | +--rw vht-max-mimo uint8 | | | +--rw freq-2-4 boolean | | | +--rw freq-5 boolean | | | +--rw auth | | | +--rw (auth-type)? | | | +--:(personal) | | | | +--rw personal! | | | | +--rw cipher cipher-auth-t | | | | +--rw password? string | | | +--:(eap-tls) | | | | +--rw eap-tls! | | | | +--rw cipher cipher-auth-t | | | | +--rw ca-cert? string | | | | +--rw client-cert? string | | | | +--rw identity? string | | | | +--rw private-key? string | | | +--:(eap-ttls) | | | | +--rw eap-ttls! | | | | +--rw cipher cipher-auth-t | | | | +--rw ca-cert? string | | | | +--rw identity? string | | | | +--rw anonymous-identity? string | | | | +--rw password? string | | | +--:(peap) | | | +--rw peap! | | | +--rw cipher cipher-auth-t | | | +--rw ca-cert? string | | | +--rw identity? string | | | +--rw anonymous-identity? string | | | +--rw password? string | | +--rw mobile | | | +--rw apn? string | | | +--rw pdp_type string | | | +--rw rat_band mobile-rat-band-t | | | +--rw rat_mode mobile-rat-mode-t | | +--rw interface-config | | +--rw ipv4-address | | | +--rw (address-type)? | | | +--:(static) | | | | +--rw static! | | | | +--rw address tailf:ipv4-address-and-prefix-length | | | | +--rw routes* [network] | | | | | +--rw network tailf:ipv4-address-and-prefix-length | | | | | +--rw gateway inet:ipv4-address | | | | +--rw dns-servers* inet:ipv4-address | | | +--:(dhcp) | | | +--rw dhcp! | | | +--rw vendor-id? string | | +--rw ipv6-address | | +--rw (address-type)? | | +--:(static) | | | +--rw static! | | | +--rw address tailf:ipv6-address-and-prefix-length | | | +--rw routes* [network] | | | | +--rw network tailf:ipv6-address-and-prefix-length | | | | +--rw gateway inet:ipv6-address | | | +--rw dns-servers* inet:ipv6-address | | +--:(dhcp) | | | +--rw dhcp! | | | +--rw vendor-id? string | | +--:(slaac) | | +--rw slaac! | | +--rw dns-servers* inet:ipv6-address | +--rw ssh-keys | +--rw ssh-key* [name] | +--rw name string | +--rw ssh-key-value string | +--ro test-agent? -> /accounts/account/test-agents/test-agent/name
We proceed in the following steps, which are detailed in the following:
- At the outset, the Paragon Active Assurance account "demo" has no Test Agents in its inventory.
- A Test Agent called "vta1" is created using ncclient. At this stage, no real Test Agent exists yet (that is, it has not yet been started).
- The Test Agent is deployed in OpenStack. (Deployment on that platform is chosen here as one possibility among others.)
- The Test Agent connects to the Control Center account "demo" and is now ready for use.
Step 1: At the outset, there are no Test Agents in the account "demo". See the screenshot below from the Control Center GUI.
Step 2: A Test Agent is created in Control Center using the Python NETCONF client "ncclient". Below is ncclient code for creating a Test Agent having one physical interface with a DHCP address:
import argparse from ncclient import manager parser = argparse.ArgumentParser(description='Test creating Test Agent') parser.add_argument('--host', help='The hostname where ConfD is found', required=True) parser.add_argument('--port', help='The port to connect to ConfD', required=True) parser.add_argument('--username', help='The username to connect to ConfD', required=True) parser.add_argument('--password', help='Password to the ConfD account', required=True) parser.add_argument('--netrounds-account', help='The NCC account short name', required=True) parser.add_argument('--test-agent-name', help='Name of Test Agent', required=True) args = parser.parse_args() with manager.connect(host=args.host, port=args.port, username=args.username, password=args.password, hostkey_verify=False) as m: # Create Test Agent in Control Center xml = """<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <accounts xmlns="http://ncc.netrounds.com"> <account> <name>demo</name> <test-agents> <test-agent> <name>vta1</name> <description/> <ntp> <interface>eth0</interface> <server>time.google.com</server> </ntp> <management> <interface>eth0</interface> </management> <interfaces> <interface> <name>eth0</name> <description/> <interface-type>physical</interface-type> <mac>fa:16:3e:ec:b3:a8</mac> <mtu>1400</mtu> <speed>auto</speed> <interface-config> <ipv4-address> <dhcp/> </ipv4-address> <ipv6-address></ipv6-address> </interface-config> </interface> </interfaces> <tags> <tag> <name>Tag 1</name> </tag> </tags> </test-agent> </test-agents> </account> </accounts> </config> """.format( account=args.netrounds_account, testagent=args.test_agent_name ) print m.edit_config(target='running', config=xml)
The code preceding with manager.connect(...)
is omitted from
subsequent example code snippets.
An NTP server is configured on eth0, and eth0 is also the management interface (that is, the interface that connects to Control Center).
A Test Agent Application does not currently allow configuring interfaces. For this reason, from version 2.34.0 onward, it is possible to omit the interface configuration in the YANG schema. The corresponding XML is therefore radically simplified in this case:
# Create Test Agent Application in Control Center xml = """<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <accounts xmlns="http://ncc.netrounds.com"> <account> <name>demo</name> <test-agents> <test-agent> <name>vta2</name> <description/> <tags> <tag> <name>Tag 2</name> </tag> </tags> </test-agent> </test-agents> </account> </accounts> </config>"""
Once the Test Agent has been created, it exists in the configuration database and in Control Center. See the screenshot below of the Test Agent inventory, showing the Test Agent "vta1":
Step 3: It is now time to deploy the Test Agent "vta1" in OpenStack.
The Test Agent will use cloud-init user data to retrieve the information on how to
connect to Control Center. Specifically, the user data text file has the
following contents (Note that the #cloud-config
and netrounds_test_agent
lines must be present, and that the
remaining lines must be indented):
#cloud-config netrounds_test_agent: name: MyvTA # Name of vTA to appear in Control Center inventory email: john.doe@example.com # Email you use when logging in to the system password: secret # Login password account: theaccount # Account name server: <login-server>:<port> # Control Center host and port (default == SaaS) # Note: With an IPv6 server address the whole string # including port must be in double quotes
For further information, please refer to the document [DEPRECATED] How to Deploy Virtual Test Agents in OpenStack.
Once the Test Agent has been deployed and has connected to Control Center, the configuration will be pushed from Control Center to the Test Agent.
Step 4: The Test Agent is now online in Control Center and has obtained its configuration. The Test Agent is ready for use in tests and monitoring. See these sections:
Listing the Test Agents in Your Paragon Active Assurance Account
Below is example ncclient Python code for listing the Test Agents in a Paragon Active Assurance account:
import argparse from ncclient import manager from ncclient.xml_ import to_ele, to_xml # (server and account details omitted) with manager.connect(host=args.host, port=args.port, username=args.username, password=args.password, hostkey_verify=False) as m: # Get config subtree # Get Test Agents from account filter = """<accounts xmlns="http://ncc.netrounds.com"> <account> <name>{account}</name> <test-agents></test-agents> </account> </accounts>""".format(account=args.netrounds_account) ele = to_ele(m.get_config(source='running', filter=('subtree', xml)).data_xml) print to_xml(ele, encoding='UTF-8', pretty_print=True)
Running this code gives output like that below:
<?xml version="1.0" ?> <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <accounts xmlns="http://ncc.netrounds.com"> <account> <name xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">demo</name> <test-agents> <test-agent> <name>vta1</name> <description/> <ntp> <interface>eth0</interface> <server>time.google.com</server> </ntp> <management> <interface>eth0</interface> </management> <interfaces> <interface> <name>eth0</name> <description/> <interface-type>physical</interface-type> <mac>fa:16:3e:ec:b3:a8</mac> <mtu>1400</mtu> <speed>auto</speed> <interface-config> <ipv4-address> <dhcp/> </ipv4-address> <ipv6-address></ipv6-address> </interface-config> </interface> </interfaces> </test-agent> </test-agents> </account> </accounts> </data>
Deleting a Test Agent
After a test has completed, it might be relevant in some use cases to delete the Test Agent.
Below is a code snippet showing how to do this with ncclient:
with manager.connect(host=args.host, port=args.port, username=args.username, password=args.password, hostkey_verify=False) as m: # Get config subtree # Delete Test Agent from account xml = """<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <accounts xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="http://ncc.netrounds.com"> <account> <name>demo</name> <test-agents> <test-agent nc:operation="delete"> <name>{test_agent}</name> </test-agent> </test-agents> </account> </accounts> </config>""".format(test_agent="vta2") test_agents = m.edit_config(target='running', config=xml)
NETCONF Notifications
Below, we present a simple example script for listening to all incoming NETCONF notifications from Control Center. These notifications are sent whenever certain events take place, such as a Test Agent going offline or a user-initiated test being completed. Based on the information carried in the notifications, users can assign automated follow-up actions in the orchestrator.
with manager.connect(host=args.host, port=args.port, username=args.username, password=args.password, hostkey_verify=False) as m: data = m.create_subscription(stream_name='ncc') # This will put ncclient in a state where it listens for notifications, # triggered for instance by a Test Agent being unplugged. # The example code below simply reads one notification. What to do with it is left # to the creativity of the user. while True: notification = m.take_notification() print notification._raw
When the above script is executed, ncclient will present the received notification in structured XML. See the example output below, which shows a Test Agent going offline unexpectedly.
<ncclient.operations.notify.Notification object at 0x7f30242b6f10> <?xml version="1.0" encoding="UTF-8"?> <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"><eventTime> 2017-02-03T15:09:55.939156+00:00</eventTime> <test-agent-status-change xmlns='http://ncc.netrounds.com'> <account>demo</account> <test-agent>HW1</test-agent> <status>offline</status> </test-agent-status-change> </notification>