# MWT SDN Plugtests 4 materials Tools and test suites developed for the 4th ETSI mWT SDN Plugtests ETSI is organizing the 4th mWT (millimetre Wave Transmission) SDN (Software Defined Network) Plugtestsā„¢ event under the mWT Plugtests Programme. Contact: plugtests@etsi.org. ## How to get Write Access to this repository Log into this ETSI Forge Gitlab server using your ETSI On Line account (EOL account or ETSI Portal account). Take a note of your username and send it to Ultan Mulligan or Xavier Piednoir, requesting access. ## lncc.py Tutorial ### Script launch & first steps The Lightweight NETCONF Controller is build on top of _cmd2_ Python package : it benefits from all [built-in features](https://cmd2.readthedocs.io/en/stable/features/index.html): [help](https://cmd2.readthedocs.io/en/stable/features/help.html), [history](https://cmd2.readthedocs.io/en/stable/features/history.html), [script](https://cmd2.readthedocs.io/en/stable/features/scripting.html) and more... Start as any script: `python3 lncc.py` or `./lncc.py`. * You will get help using the `help` command. More verbose will be available in future, using `help ` or `command --help`. * You will exit using `quit` command or EOF (Ctrl+D).
help & quit commands feedback ```console $ python3 lncc.py Welcome to the Lightweight NETCONF Controller lncc.py Type 'help' for more information (Cmd) help Documented commands (use 'help -v' for verbose/'help ' for details): Input & output handling ======================= sleep table NETCONF ======= connect netconf Parameter management ==================== mapping ne Uncategorized ============= alias help macro run_pyscript set shortcuts edit history quit run_script shell (Cmd) quit $ ```
"help netconf" commands feedback ```console $ python3 lncc.py Welcome to the Lightweight NETCONF Controller lncc.py Type 'help' for more information (Cmd) help netconf Usage: netconf [-h] [--reply REPLY-NAME] {get, get-config, edit-config, copy-config, delete-config, lock, Run NETCONF operations on NEs optional arguments: -h, --help show this help message and exit --reply REPLY-NAME NETCONF operations: {get, get-config, edit-config, copy-config, delete-config, lock, unlock, clos (Cmd) (Cmd) help netconf Usage: netconf [-h] [--reply REPLY-NAME] {get, get-config, edit-config, copy-config, delete-config, lock, unlock, close-session, kill-session, commit, discard-changes, cancel-commit, validate} ... Run NETCONF operations on NEs optional arguments: -h, --help show this help message and exit --reply REPLY-NAME NETCONF operations: {get, get-config, edit-config, copy-config, delete-config, lock, unlock, close-session, kill-session, commit, discard-changes, cancel-commit, validate} (Cmd) quit ```
### Quick example - Adding NEs or loading NEs --> `ne add`, - connect to NEs --> `connect`, - run NETCONF operations on NEs (get, edit-config, close-session, ...), -> The results is stored with the operation's name. - transform NETCONF operations replies, - write tranformed informations as file. #### Add NEs ``` (Cmd) ne add my_ne1 --host 172.20.183.168 --username netconfuser --password NotSoSecret123* NE my_ne1 added, current: 1 NEs (Cmd) ne add my_ne2 --host 172.20.183.169 --username netconfuser --password NotSoSecret123* --port 830 NE my_ne2 added, current: 2 NEs ``` You can save NEs configuration in a YAML file using `ne dump my_nes.yaml`. Then load using `ne load my_nes.yaml` #### Connect to all NEs ``` (Cmd) connect 2 new connections, 2 total: ['my_ne1', 'my_ne2'] ``` #### Run NETCONF operations ``` (Cmd) netconf get --filter-file interface_type_microwaveCarrierTermination_filter.xml NETCONF operation completed: 2 NEs, stored in 'get' ``` #### Transform the results ``` (Cmd) table from_xml --xsl-transform get-interface-transform.xsl New tables 'get' in each NE, build from XML stored in 'get' (Cmd) table concat Table 'get' available for group (Cmd) table to_excel interfaces.xlsx Wrote Excel file interfaces.xlsx, with 1 tabs: args.tables ``` ### Creating a script If the commands you can convert We rely on _cmd2_ build-in commands: [`history --script`](https://cmd2.readthedocs.io/en/stable/features/history.html#for-users) then `run_script`. Once the set of command make a interesting scenario, you can save it as TXT script file. You can edit this TXT script with you usual editor (type `edit` build-in command to start vim). ``` (Cmd) history --script > get_interface_inventory_script2.txt (Cmd) ``` Then let's play again the same command sequence, using `run_script` command. You may see errors if you keep adding NEs taht exists. ``` (Cmd) run_script get_interface_inventory_script2.txt Error: NE my_ne1 already exist Error: NE my_ne2 already exist 0 new connections, 2 total: ['my_ne1', 'my_ne2'] NETCONF operation completed: 2 NEs, stored in 'get' New tables 'get' in each NE, build from XML stored in 'get' Table 'get' available for group Wrote Excel file interfaces.xlsx, with 1 tabs: args.tables ``` ### Creating a transcript Transcripts enable us to compare the script behavior from different NEs. Transcript records both the commands input and their ouputs. Transcript are created with the ['--transcript' argument of the 'run_script'](https://cmd2.readthedocs.io/en/stable/features/transcripts.html) command. In order to compare the behavior, we need to redirect the feedback (~stderr) to the ouput (~stdout), using the `set feedback_to_output true`command. ``` (Cmd) set feedback_to_output true (Cmd) run_script get_interface_inventory_script2.txt --transcript get_interface_inventory_transcript2.txt 7 commands and their outputs saved to transcript file '/home/jean/lncc/get_interface_inventory_transcript2.txt' ``` ### Test a transcript [Transcipt](https://cmd2.readthedocs.io/en/stable/features/transcripts.html#running-a-transcript) have to be run from your shell (not inside the lncc.py!). It will play the commands and will compare the output of these commands with the content of the transcript. ```console $ python3 lncc.py --test get_interface_inventory_transcript.txt =========================================== cmd2 transcript test ============================================ platform linux -- Python 3.8.10, cmd2-2.4.0, readline-RlType.GNU cwd: /home/jean/lncc cmd2 app: lncc.py collected 1 transcript . ---------------------------------------------------------------------- Ran 1 test in 3.459s OK =================================== 1 transcript passed in 3.459 seconds ==================================== $ ``` ## Sharing your transcript The command-line doesn't containt vendor-specific informations: they can be share to check that the behavior is common. ## Already available transcripts 2 transcript are already available in [script directory](https://forge.etsi.org/rep/sdn/mwt/mwt-sdn-plugtests-4-materials/-/tree/main/scripts), as of May 9th 2022. You already have the possibility to test them on your equipements. - _get_interface_inventory_transcript.txt_ -- Basically the scenario described in this tutorial - _set_tx_power_transcript.txt_
get_interface_inventory: script & transcript ```console $ cat get_interface_inventory_script.txt # get_interface_inventory_script.txt : script for Lightweight NETCONF controlleur lncc.py # run me using: lncc.py 'run_script set_tx_power_script.txt' quit set feedback_to_output true ne load ne.yaml # set logging_config logging_config.yaml connect netconf get --filter-file interface_type_microwaveCarrierTermination_filter.xml netconf close-session table from_xml --xsl-transform get-interface-transform.xsl table concat table to_excel interfaces.xlsx ``` ```console $ cat get_interface_inventory_transcript.txt (Cmd) # get_interface_inventory_script.txt : script for Lightweight NETCONF controlleur lncc.py (Cmd) # run me using: lncc.py 'run_script set_tx_power_script.txt' quit (Cmd) set feedback_to_output true feedback_to_output - was: False now: True (Cmd) ne load ne.yaml Loading complete: 2 new NEs: ['ne1', 'ne2'] (Cmd) # set logging_config logging_config.yaml (Cmd) connect 2 new connections, 2 total: ['ne1', 'ne2'] (Cmd) netconf get --filter-file interface_type_microwaveCarrierTermination_filter.xml NETCONF operation completed: 2 NEs, stored in 'get' (Cmd) netconf close-session NETCONF operation completed: 2 NEs, stored in 'close-session' (Cmd) table from_xml --xsl-transform get-interface-transform.xsl New tables 'get' in each NE, build from XML stored in 'get' (Cmd) table concat Table 'get' available for group (Cmd) table to_excel interfaces.xlsx Wrote Excel file interfaces.xlsx, with 1 tabs: args.tables ```
set_tx_power: script & transcript ```console $ cat set_tx_power_script.txt # set_tx_power_script.txt for Lightweight NETCONF controlleur lncc.py # run using: lncc.py 'run_script set_tx_power_script.txt' quit set feedback_to_output true ne load ne.yaml mapping add set-power --ne ne1 '{if-name: RTL-63-255-1, tx-power: -8}' mapping add set-power --ne ne2 '{if-name: RTL-63-255-1, tx-power: -7}' connect netconf lock netconf edit-config --config-template set_tx_power.xml.pyformat --mappings set-power netconf commit --confirmed sleep 10 netconf commit netconf unlock netconf close-session ``` ```console $ cat set_tx_power_transcript.txt (Cmd) # set_tx_power_script.txt for Lightweight NETCONF controlleur lncc.py (Cmd) # run using: lncc.py 'run_script set_tx_power_script.txt' quit (Cmd) set feedback_to_output true feedback_to_output - was: False now: True (Cmd) ne load ne.yaml Loading complete: 2 new NEs: ['ne1', 'ne2'] (Cmd) mapping add set-power --ne ne1 '{if-name: RTL-63-255-1, tx-power: -8}' (Cmd) mapping add set-power --ne ne2 '{if-name: RTL-63-255-1, tx-power: -7}' (Cmd) connect 2 new connections, 2 total: ['ne1', 'ne2'] (Cmd) netconf lock NETCONF operation completed: 2 NEs, stored in 'lock' (Cmd) netconf edit-config --config-template set_tx_power.xml.pyformat --mappings set-power NETCONF operation completed: 2 NEs, stored in 'edit-config' (Cmd) netconf commit --confirmed NETCONF operation completed: 2 NEs, stored in 'commit' (Cmd) sleep 10 Sleeping for 10 seconds (Cmd) netconf commit NETCONF operation completed: 2 NEs, stored in 'commit' (Cmd) netconf unlock NETCONF operation completed: 2 NEs, stored in 'unlock' (Cmd) netconf close-session NETCONF operation completed: 2 NEs, stored in 'close-session' ```
### Dependencies * [Python 3](http://python.org) * [Python 3 packages](https://forge.etsi.org/rep/sdn/mwt/mwt-sdn-plugtests-4-materials/-/tree/main/requirements.txt) Sometimes the underlying package requirements may change for `lncc.py`. If you run it from scratch, you can manually update these requirements by executing something like: ``` pip3 install --upgrade -r requirements.txt ``` ## License The content of the present repository is released under the BSD-3 Clause license.