├── .gitignore ├── LICENSE.md ├── README.md ├── package-meta-data.xml ├── python └── netsim_tool │ ├── __init__.py │ ├── main.py │ ├── main.pyc │ ├── shell_commands.py │ ├── shell_commands.pyc │ ├── test_create_network.py │ └── test_create_network.pyc └── src ├── Makefile └── yang └── cli-netsim-tool.yang /.gitignore: -------------------------------------------------------------------------------- 1 | main.pyc 2 | shell_commands.pyc 3 | test_create_network.pyc 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # LICENSE 2 | 3 | Copyright 2018 Simon Spehar 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | https://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## netsim-tool 2 | A package wrapping netsim commands. Available **only for NSO local-install**. Tested on Ubuntu 16.04. 3 | 4 | ## Purpose 5 | netsim-tool enables you to easily add new netsim networks, multiple devices to existing networks and most of other commands 6 | otherwise available with _ncs-netsim_ command. List of available commands below. 7 | * create-network 8 | * create-device 9 | * delete-network 10 | * add-device 11 | * start 12 | * stop 13 | * is-alive 14 | * list 15 | * load 16 | * update-network 17 | 18 | ## Documentation 19 | Apart from this README, please refer to the python code and associated YANG file. 20 | 21 | ## Dependencies 22 | * NSO 4.3.6+ Local installation (Probably works on older versions aswell but not tested) 23 | * Python 2.7+ or 3+ 24 | * Python Popen module 25 | 26 | ## Build instructions 27 | make -C /packages/netsim-tool/src all 28 | 29 | ## Usage examples 30 | ### config 31 | User can configure default ports of running netsim processes and netsim-dir, which represents the folder where netsim network and devices are created. 32 | In this way it's easy to switch between multiple netsim networks. Users should specify absolute path for a directory where they want to create the network. 33 | Default value is _/netsim-lab_. 34 | ```admin@ncs(config)# netsim config netsim-dir /ios-netsim-lab``` 35 | ### create-device 36 | New networks can be created by using _create-network_ or _create-device_ actions. Both will create new network and load devices to NSO cdb. 37 | ```admin@ncs# netsim create-device device-name R1 ned-id cisco-ios``` 38 | ### add-device 39 | Users can add one or multiple devices to existing networks. This action also creates devices and loads them to NSO cdb. 40 | ```netsim add-device device-name [ R2 R3 R4 ] ned-id cisco-ios``` 41 | ### start 42 | Netsim devices can be started or stopped using start action. If user provides list of devices then only those will be started. If he skips the list all of netsim devices will be started. 43 | ```admin@ncs(config)# netsim start device-name [ R1 R3 ]``` 44 | ### load 45 | Using netsim-tool load users can load existing netsim networks into new NSO running instance. Issuing this command will load devices in netsim network specified in _config->netsim-dir_. 46 | ```admin@ncs(config)# netsim load``` 47 | ### update-network 48 | When changing NSO versions, existing netsim networks might stop working. With update-network action users can change schema files (.fxs) 49 | in the network with the ones from current NSO, which enables netsim devices to work with current version. 50 | ```netsim update-network ncs-run /home/cisco/ncs-run``` 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /package-meta-data.xml: -------------------------------------------------------------------------------- 1 | 2 | cli-netsim-tool 3 | 1.0 4 | A library of actions for adding netsim devices 5 | 4.3.6 6 | 7 | 8 | main 9 | 10 | netsim_tool.main.Main 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /python/netsim_tool/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NSO-developer/cli-netsim-tool/bb30192f26075f88e6a5a100dd72dba0f69b158a/python/netsim_tool/__init__.py -------------------------------------------------------------------------------- /python/netsim_tool/main.py: -------------------------------------------------------------------------------- 1 | # -*- mode: python; python-indent: 4 -*- 2 | # 3 | # Copyright 2018 Simon Spehar 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | import _ncs 18 | import ncs 19 | import os 20 | from collections import namedtuple 21 | from ncs.application import Service 22 | from ncs.dp import Action 23 | from netsim_tool.shell_commands import NetsimShell 24 | 25 | 26 | class NetsimTool(Action): 27 | @Action.action 28 | def cb_action(self, uinfo, name, kp, input, output): 29 | self.log.info('action name: ', name) 30 | success = '' 31 | error = '' 32 | message = namedtuple('Message', 'success error') 33 | r = setup_maapi() 34 | set_ports(r) 35 | 36 | # some actions can take device list as an input. I.e. start action 37 | devices = input.device_name if hasattr(input, 'device_name') and input.device_name else '' 38 | ned_id = input.ned_id if hasattr(input, 'ned_id') else None 39 | netsim_dir = r.netsim.config.netsim_dir 40 | 41 | netsim = NetsimShell(ned_id, netsim_dir) 42 | 43 | # Actions router 44 | 45 | if name == 'create-network': 46 | number = input.number 47 | prefix = '' if input.prefix is None else input.prefix 48 | response = self.create_network_action(netsim, number, prefix) 49 | action_output(output, response) 50 | 51 | if name == 'create-device': 52 | response = self.create_device_action(netsim, devices) 53 | action_output(output, response) 54 | 55 | if name == 'delete-network': 56 | response = self.delete_network_action(netsim) 57 | action_output(output, response) 58 | 59 | if name == 'add-device': 60 | for device in devices: 61 | result = self.add_device_action(netsim, device) 62 | success += result.success 63 | error += result.error 64 | action_output(output, message(success, error)) 65 | 66 | elif name == 'start': 67 | # list of devices or all 68 | if devices: 69 | for device in devices: 70 | result = self.start_device_action(netsim, device) 71 | success += result.success 72 | error += result.error 73 | else: 74 | result = self.start_device_action(netsim, '') 75 | success += result.success 76 | error += result.error 77 | 78 | action_output(output, message(success, error)) 79 | 80 | elif name == 'stop': 81 | # list of devices or all 82 | if devices: 83 | for device in devices: 84 | result = self.stop_device_action(netsim, device) 85 | success += result.success 86 | error += result.error 87 | else: 88 | result = self.stop_device_action(netsim, '') 89 | success += result.success 90 | error += result.error 91 | 92 | action_output(output, message(success, error)) 93 | 94 | elif name == 'is-alive': 95 | # list of devices or all 96 | if devices: 97 | for device in devices: 98 | state = self.alive_action(netsim, device) 99 | success += state.success 100 | error += state.error 101 | else: 102 | state = self.alive_action(netsim, '') 103 | success = state.success 104 | error = state.error 105 | 106 | action_output(output, message(success, error)) 107 | 108 | elif name == 'list': 109 | response = self.list_action(netsim) 110 | action_output(output, response) 111 | 112 | elif name == 'load': 113 | response = self.load_action(netsim) 114 | success = "Netsim devices loaded!" 115 | action_output(output, message(success, response.error)) 116 | 117 | elif name == 'update-network': 118 | ncs_run = input.ncs_run 119 | response = self.update_action(netsim, ncs_run) 120 | 121 | action_output(output, response) 122 | 123 | # Actions implementation 124 | 125 | def create_network_action(self, netsim, number, prefix): 126 | """ 127 | Used for creating netsim network with number of devices and prefix for name 128 | """ 129 | self.log.info('Creating new netsim network') 130 | response = None 131 | while True: 132 | # Create the network 133 | create_response = netsim.create_network(number, prefix) 134 | response = create_response 135 | if create_response.error: 136 | break 137 | # Init netsim device configuration 138 | init_response = netsim.init_config('') 139 | if init_response.error: 140 | response = init_response 141 | break 142 | # Load init configuration to cdb 143 | load_response = netsim.load_config() 144 | if load_response.error: 145 | response = load_response 146 | break 147 | # all operations finished 148 | break 149 | 150 | return response 151 | 152 | def create_device_action(self, netsim, device): 153 | """ 154 | Used for creating a network with one device. 155 | """ 156 | self.log.info('Creating new netsim network with device ', device) 157 | response = None 158 | while True: 159 | # Create the network 160 | create_response = netsim.create_device(device) 161 | response = create_response 162 | if create_response.error: 163 | break 164 | # Init netsim device configuration 165 | init_response = netsim.init_config(device) 166 | if init_response.error: 167 | response = init_response 168 | break 169 | # Load init configuration to cdb 170 | load_response = netsim.load_config() 171 | if load_response.error: 172 | response = load_response 173 | break 174 | # all operations finished 175 | break 176 | 177 | return response 178 | 179 | def delete_network_action(self, netsim): 180 | self.log.info('Deleting {} netsim network'.format(os.environ["NETSIM_DIR"])) 181 | response = netsim.delete_network() 182 | 183 | return response 184 | 185 | def add_device_action(self, netsim, device): 186 | """ 187 | Adding one or more devices to existing netsim network 188 | """ 189 | self.log.info('Adding device {} to the network'.format(device)) 190 | response = None 191 | while True: 192 | # Add device to the network 193 | add_response = netsim.add_device(device) 194 | response = add_response 195 | if add_response.error: 196 | break 197 | # Init netsim device configuration 198 | init_response = netsim.init_config(device) 199 | if init_response.error: 200 | response = init_response 201 | break 202 | # Load init configuration to cdb 203 | load_response = netsim.load_config() 204 | if load_response.error: 205 | response = load_response 206 | break 207 | # all operations finished 208 | break 209 | 210 | return response 211 | 212 | def start_device_action(self, netsim, device): 213 | self.log.info('Starting: ', device) 214 | response = netsim.start_device(device) 215 | 216 | return response 217 | 218 | def stop_device_action(self, netsim, device): 219 | self.log.info('Stopping: ', device) 220 | response = netsim.stop_device(device) 221 | 222 | return response 223 | 224 | def alive_action(self, netsim, device): 225 | self.log.info('Checking if {} is alive'.format(device)) 226 | response = netsim.device_alive(device) 227 | 228 | return response 229 | 230 | def list_action(self, netsim): 231 | self.log.info('Listing netsim devices') 232 | response = netsim.list_netsim() 233 | 234 | return response 235 | 236 | def load_action(self, netsim): 237 | self.log.info('Loading netsim devices') 238 | response = netsim.load_config() 239 | 240 | return response 241 | 242 | def update_action(self, netsim, ncs_run): 243 | """ 244 | Updating netsim devices in current network with new fxs from the NEDs in updated version of NSO. 245 | """ 246 | self.log.info('Updating netsim') 247 | response = netsim.update_netsim(ncs_run) 248 | 249 | return response 250 | 251 | 252 | def action_output(output, response): 253 | if response.success and response.error: 254 | output.result = False 255 | output.info = response.success + '\n' + 'Error:\n' + response.error 256 | elif response.success: 257 | output.result = True 258 | output.info = response.success 259 | else: 260 | output.result = False 261 | output.info = response.error 262 | 263 | 264 | def set_ports(r): 265 | """ 266 | Users can change default ports on which netsim processes are running 267 | """ 268 | ipc_port = str(r.netsim.config.IPC_PORT) 269 | netconf_ssh_port = str(r.netsim.config.NETCONF_SSH_PORT) 270 | netconf_tcp_port = str(r.netsim.config.NETCONF_SSH_PORT) 271 | snmp_port = str(r.netsim.config.SNMP_PORT) 272 | cli_ssh_port = str(r.netsim.config.CLI_SSH_PORT) 273 | 274 | os.environ["IPC_PORT"] = ipc_port 275 | os.environ["NETCONF_SSH_PORT"] = netconf_ssh_port 276 | os.environ["NETCONF_TCP_PORT"] = netconf_tcp_port 277 | os.environ["SNMP_PORT"] = snmp_port 278 | os.environ["CLI_SSH_PORT"] = cli_ssh_port 279 | 280 | netsim_dir = r.netsim.config.netsim_dir 281 | os.environ["NETSIM_DIR"] = netsim_dir 282 | 283 | 284 | def setup_maapi(): 285 | m = ncs.maapi.Maapi() 286 | m.start_user_session('admin', 'system', []) 287 | t = m.start_trans(ncs.RUNNING, ncs.READ_WRITE) 288 | r = ncs.maagic.get_root(t) 289 | return r 290 | 291 | 292 | class Main(ncs.application.Application): 293 | def setup(self): 294 | self.log.info('Main RUNNING') 295 | self.register_action('netsim-tool', NetsimTool) 296 | 297 | def teardown(self): 298 | self.log.info('Main FINISHED') 299 | -------------------------------------------------------------------------------- /python/netsim_tool/main.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NSO-developer/cli-netsim-tool/bb30192f26075f88e6a5a100dd72dba0f69b158a/python/netsim_tool/main.pyc -------------------------------------------------------------------------------- /python/netsim_tool/shell_commands.py: -------------------------------------------------------------------------------- 1 | # -*- mode: python; python-indent: 4 -*- 2 | # 3 | # Copyright 2018 Simon Spehar 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | from subprocess import Popen, PIPE 18 | from collections import namedtuple 19 | import os 20 | 21 | """Methods executing shell commands""" 22 | 23 | 24 | class NetsimShell(object): 25 | def __init__(self, ned_id, netsim_dir, device_config=None): 26 | self.ned_id = ned_id 27 | self.netsim_dir = netsim_dir 28 | self.device_config = device_config 29 | self.result = namedtuple('Result', 'success error') 30 | 31 | def create_network(self, number, prefix): 32 | response = self.execute( 33 | "ncs-netsim --dir {} create-network {} {} {}".format(self.netsim_dir, self.ned_id, number, prefix)) 34 | return response 35 | 36 | def create_device(self, name): 37 | response = self.execute("ncs-netsim --dir {} create-device {} {}".format(self.netsim_dir, self.ned_id, name)) 38 | return response 39 | 40 | def delete_network(self): 41 | response = self.execute("ncs-netsim --dir {} delete-network".format(self.netsim_dir)) 42 | return response 43 | 44 | def add_device(self, name): 45 | response = self.execute("ncs-netsim --dir {} add-device {} {}".format(self.netsim_dir, self.ned_id, name)) 46 | return response 47 | 48 | def init_config(self, name): 49 | response = self.execute("ncs-netsim --dir {} ncs-xml-init {}".format(self.netsim_dir, name)) 50 | # Save config to the object 51 | if not response.error: 52 | self.device_config = response.success 53 | return response 54 | 55 | def load_config(self): 56 | response = self.execute("ncs_load -l -m", self.device_config) 57 | return response 58 | 59 | def start_device(self, name): 60 | response = self.execute("ncs-netsim --dir {} start {}".format(self.netsim_dir, name)) 61 | return response 62 | 63 | def stop_device(self, name): 64 | response = self.execute("ncs-netsim --dir {} stop {}".format(self.netsim_dir, name)) 65 | return response 66 | 67 | def device_alive(self, name): 68 | response = self.execute("ncs-netsim --dir {} is-alive {}".format(self.netsim_dir, name)) 69 | return response 70 | 71 | def list_netsim(self, filter=None): 72 | response = self.execute("ncs-netsim --dir {} list".format(self.netsim_dir)) 73 | return response 74 | 75 | def update_netsim(self, ncs_dir): 76 | response = self.result 77 | # Find all devices 78 | device_paths = [device.split()[5][4:] for device in self.list_netsim()[0].splitlines() if "dir=/" in device] 79 | 80 | for path in device_paths: 81 | fxs_files = [file for file in os.listdir(path) if file.endswith('.fxs')] 82 | for file in fxs_files: 83 | response = self.execute("find -L {} -name {}".format(ncs_dir, file)) 84 | if response.success: 85 | netsim_fxs = [x for x in response.success.splitlines() if "/netsim/" + file in x][0] 86 | if netsim_fxs: 87 | response = self.execute("cp {} {}".format(netsim_fxs, path)) 88 | else: 89 | response = self.result(None, "Couldn't find {} in your running directory\n" 90 | "Check if you have the appropriate NEDs.".format(file)) 91 | if response.error: 92 | break 93 | if response.error: 94 | break 95 | 96 | if not response.error: 97 | response = self.result('Netsim updated!', None) 98 | 99 | return response 100 | 101 | def execute(self, command, stdin=None): 102 | p = Popen(command.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE) 103 | out, err = p.communicate(stdin) 104 | return self.result(out, err) 105 | -------------------------------------------------------------------------------- /python/netsim_tool/shell_commands.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NSO-developer/cli-netsim-tool/bb30192f26075f88e6a5a100dd72dba0f69b158a/python/netsim_tool/shell_commands.pyc -------------------------------------------------------------------------------- /python/netsim_tool/test_create_network.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from shell_commands import NetsimShell 3 | import ncs 4 | import _ncs 5 | 6 | 7 | def set_maapi(): 8 | m = ncs.maapi.Maapi() 9 | m.start_user_session('admin', 'system', []) 10 | t = m.start_trans(ncs.RUNNING, ncs.READ_WRITE) 11 | r = ncs.maagic.get_root(t) 12 | return r 13 | 14 | 15 | class TestMain(unittest.TestCase): 16 | def setUp(self): 17 | self.r = set_maapi() 18 | 19 | def test_non_existing_device_does_not_init_config(self): 20 | netsim = NetsimShell('juniper-junos', self.r.netsim.config.netsim_dir) 21 | success, error = netsim.init_config('this_device_shouldnt_exist') 22 | self.assertTrue(error) 23 | 24 | 25 | if __name__ == '__main__': 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /python/netsim_tool/test_create_network.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NSO-developer/cli-netsim-tool/bb30192f26075f88e6a5a100dd72dba0f69b158a/python/netsim_tool/test_create_network.pyc -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: fxs 2 | .PHONY: all 3 | 4 | # Include standard NCS examples build definitions and rules 5 | include $(NCS_DIR)/src/ncs/build/include.ncs.mk 6 | 7 | SRC = $(wildcard yang/*.yang) 8 | DIRS = ../load-dir java/src/$(JDIR)/$(NS) 9 | FXS = $(SRC:yang/%.yang=../load-dir/%.fxs) 10 | 11 | ## Uncomment and patch the line below if you have a dependency to a NED 12 | ## or to other YANG files 13 | # YANGPATH += ../..//src/ncsc-out/modules/yang \ 14 | # ../..//src/yang 15 | 16 | NCSCPATH = $(YANGPATH:%=--yangpath %) 17 | YANGERPATH = $(YANGPATH:%=--path %) 18 | 19 | fxs: $(DIRS) $(FXS) 20 | 21 | $(DIRS): 22 | mkdir -p $@ 23 | 24 | ../load-dir/%.fxs: yang/%.yang 25 | $(NCSC) `ls $*-ann.yang > /dev/null 2>&1 && echo "-a $*-ann.yang"` \ 26 | $(NCSCPATH) -c -o $@ $< 27 | 28 | clean: 29 | rm -rf $(DIRS) 30 | .PHONY: clean 31 | -------------------------------------------------------------------------------- /src/yang/cli-netsim-tool.yang: -------------------------------------------------------------------------------- 1 | module cli-netsim-tool { 2 | /* 3 | * Copyright 2018 Simon Spehar 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * https://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | **/ 17 | namespace "http://cisco.com/nso/cli-netsim-tool"; 18 | prefix cli-netsim-tool; 19 | 20 | import tailf-common { 21 | prefix tailf; 22 | } 23 | import tailf-ncs { 24 | prefix ncs; 25 | } 26 | 27 | description "A library of actions for adding netsim devices"; 28 | 29 | // ========================================================================= 30 | // REVISION 31 | // ========================================================================= 32 | 33 | revision 2018-05-06 { 34 | description 35 | "contact: sspehar@nil.com 36 | "; 37 | } 38 | 39 | // ========================================================================= 40 | // TYPEDEF 41 | // ========================================================================= 42 | 43 | typedef ned-id { 44 | type union { 45 | type enumeration { 46 | enum "juniper-junos"; 47 | enum "cisco-ios"; 48 | enum "cisco-iosxr"; 49 | enum "paloalto-panos_cli"; 50 | } 51 | type string; 52 | } 53 | } 54 | 55 | 56 | 57 | container netsim { 58 | container config { 59 | tailf:info "Netsim configuration"; 60 | leaf netsim-dir { 61 | tailf:info "Absolute path to the netsim directory"; 62 | type string; 63 | default "/netsim-lab"; 64 | } 65 | 66 | leaf IPC_PORT { 67 | tailf:info "Default 5010"; 68 | type uint32; 69 | default 5010; 70 | } 71 | 72 | leaf NETCONF_SSH_PORT { 73 | tailf:info "12022"; 74 | type uint32; 75 | default 12022; 76 | } 77 | 78 | leaf NETCONF_TCP_PORT { 79 | tailf:info "13022"; 80 | type uint32; 81 | default 13022; 82 | 83 | } 84 | 85 | leaf SNMP_PORT { 86 | tailf:info "11022"; 87 | type uint32; 88 | default 11022; 89 | } 90 | 91 | leaf CLI_SSH_PORT { 92 | tailf:info "10022"; 93 | type uint32; 94 | default 10022; 95 | } 96 | 97 | } 98 | 99 | tailf:action create-network { 100 | tailf:info "Create new Netsim network"; 101 | tailf:actionpoint netsim-tool; 102 | input { 103 | leaf ned-id { 104 | tailf:info "NED ID"; 105 | mandatory true; 106 | type ned-id; 107 | } 108 | leaf number { 109 | mandatory true; 110 | tailf:info "Number of devices"; 111 | type uint8; 112 | } 113 | leaf prefix { 114 | mandatory true; 115 | tailf:info "Prefix for devices"; 116 | type string; 117 | } 118 | } 119 | output { 120 | leaf result { 121 | type boolean; 122 | } 123 | 124 | leaf info { 125 | type string; 126 | } 127 | } 128 | } 129 | tailf:action create-device { 130 | tailf:info "Create new Netsim network with one device"; 131 | tailf:actionpoint netsim-tool; 132 | input { 133 | leaf ned-id { 134 | tailf:info "NED ID"; 135 | mandatory true; 136 | type ned-id; 137 | } 138 | leaf device-name { 139 | tailf:info "Device name"; 140 | mandatory true; 141 | type string; 142 | } 143 | } 144 | output { 145 | leaf result { 146 | type boolean; 147 | } 148 | 149 | leaf info { 150 | type string; 151 | } 152 | } 153 | } 154 | 155 | 156 | tailf:action delete-network { 157 | tailf:info "Delete currently configured Netsim network"; 158 | tailf:actionpoint netsim-tool; 159 | output { 160 | leaf result { 161 | type boolean; 162 | } 163 | 164 | leaf info { 165 | type string; 166 | } 167 | 168 | } 169 | } 170 | 171 | tailf:action add-device { 172 | tailf:info "Add device(s) to network"; 173 | tailf:actionpoint netsim-tool; 174 | input { 175 | leaf ned-id { 176 | tailf:info "NED ID"; 177 | mandatory true; 178 | type ned-id; 179 | } 180 | 181 | leaf-list device-name { 182 | type string; 183 | } 184 | } 185 | output { 186 | leaf result { 187 | type boolean; 188 | } 189 | 190 | leaf info { 191 | type string; 192 | } 193 | } 194 | } 195 | 196 | tailf:action start { 197 | tailf:info "Start Netsim device(s)"; 198 | tailf:actionpoint netsim-tool; 199 | input { 200 | leaf-list device-name { 201 | type leafref { path "/ncs:devices/ncs:device/ncs:name"; } 202 | } 203 | } 204 | output { 205 | leaf result { 206 | type boolean; 207 | } 208 | 209 | leaf info { 210 | type string; 211 | } 212 | } 213 | } 214 | 215 | tailf:action stop { 216 | tailf:info "Stop Netsim device(s)"; 217 | tailf:actionpoint netsim-tool; 218 | input { 219 | leaf-list device-name { 220 | type leafref { path "/ncs:devices/ncs:device/ncs:name"; } 221 | } 222 | } 223 | output { 224 | leaf result { 225 | type boolean; 226 | } 227 | 228 | leaf info { 229 | type string; 230 | } 231 | } 232 | } 233 | 234 | tailf:action is-alive { 235 | tailf:info "Check device(s) aliveness"; 236 | tailf:actionpoint netsim-tool; 237 | input { 238 | leaf-list device-name { 239 | type leafref { path "/ncs:devices/ncs:device/ncs:name"; } 240 | } 241 | } 242 | output { 243 | leaf result { 244 | type boolean; 245 | } 246 | 247 | leaf info { 248 | type string; 249 | } 250 | } 251 | } 252 | 253 | tailf:action list { 254 | tailf:info "List netsim devices"; 255 | tailf:actionpoint netsim-tool; 256 | output { 257 | leaf result { 258 | type boolean; 259 | } 260 | 261 | leaf info { 262 | type string; 263 | } 264 | } 265 | } 266 | 267 | tailf:action load { 268 | tailf:info "Load devices from the 'netsim-dir'"; 269 | tailf:actionpoint netsim-tool; 270 | output { 271 | leaf result { 272 | type boolean; 273 | } 274 | 275 | leaf info { 276 | type string; 277 | } 278 | } 279 | } 280 | 281 | tailf:action update-network { 282 | tailf:info "Update netsim fxs when NSO is updated"; 283 | tailf:actionpoint netsim-tool; 284 | input { 285 | //TODO: automatically find current ncs-run 286 | leaf ncs-run { 287 | tailf:info "Absolute path to current running directory"; 288 | type string; 289 | mandatory true; 290 | } 291 | } 292 | output { 293 | leaf result { 294 | type boolean; 295 | } 296 | 297 | leaf info { 298 | type string; 299 | } 300 | 301 | } 302 | } 303 | 304 | } 305 | 306 | } 307 | --------------------------------------------------------------------------------