def main(): module = AnsibleModule( argument_spec=dict( url=dict(type="str", required=True), port=dict(type="int", default=3080), user=dict(type="str", default=None), password=dict(type="str", default=None, no_log=True), project_name=dict(type="str", default=None), project_id=dict(type="str", default=None), ), required_one_of=[["project_name", "project_id"]], ) if not HAS_GNS3FY: module.fail_json(msg=missing_required_lib("gns3fy"), exception=GNS3FY_IMP_ERR) result = dict(changed=False, nodes_inventory=None, total_nodes=None) server_url = module.params["url"] server_port = module.params["port"] server_user = module.params["user"] server_password = module.params["password"] project_name = module.params["project_name"] project_id = module.params["project_id"] # Create server session server = Gns3Connector(url=f"{server_url}:{server_port}", user=server_user, cred=server_password) # Define the project if project_name is not None: project = Project(name=project_name, connector=server) elif project_id is not None: project = Project(project_id=project_id, connector=server) # Retrieve project info project.get() nodes_inventory = project.nodes_inventory() result.update(nodes_inventory=nodes_inventory, total_nodes=len(nodes_inventory.keys())) module.exit_json(**result)
def main(): module = AnsibleModule(argument_spec=dict( remote_addr=dict(type="str", required=True), port=dict(type="int", required=True), login_prompt=dict(type="list", default=None), user=dict(type="str", default=None), password=dict(type="str", default=None, no_log=True), enable_password=dict(type="str", default="", no_log=True), send_newline=dict(type="bool", default=False), prompts=dict(type="list", default=["[#$]"]), root_set_user_prompts=dict(type="list", default=None), root_set_password_prompts=dict(type="list", default=None, no_log=True), config_dialog=dict(type="bool", default=False), timeout=dict(type="dict", default=TIMEOUTS), command=dict(type="list", required=True), pause=dict(type="int", default=1), pre_login_action=dict( type="str", choices=["xr9k_reboot_node", "nxos9k_disable_poap"], default=None, ), post_login_action=dict( type="str", choices=["eos_disable_ztp", "junos_enter_cli", "xr_wait_system"], default=None, ), gns3fy_data=dict(type="dict", default=None), )) if not HAS_PEXPECT: module.fail_json(msg=missing_required_lib("pexpect"), exception=PEXPECT_IMP_ERR) result = dict(changed=False) remote_addr = module.params["remote_addr"] port = module.params["port"] login_prompt = module.params["login_prompt"] user = module.params["user"] password = module.params["password"] enable_password = module.params["enable_password"] send_newline = module.params["send_newline"] prompts = module.params["prompts"] root_set_user_prompts = module.params["root_set_user_prompts"] root_set_password_prompts = module.params["root_set_password_prompts"] config_dialog = module.params["config_dialog"] timeout = set_missing_timeouts(module.params["timeout"]) command = module.params["command"] pause = module.params["pause"] pre_login_action = module.params["pre_login_action"] post_login_action = module.params["post_login_action"] gns3fy_data = module.params["gns3fy_data"] conn = pexpect.spawn( f"telnet {remote_addr} {port}", timeout=timeout["general"], maxread=4092, encoding="utf-8", searchwindowsize=2000, ignore_sighup=True, ) # Sends newline at the beginning of the connections if send_newline: conn.sendline("\r") # Pre-login actions: Depends on the platform and image, for example it can be to # reboot the node or disable POAP if pre_login_action: # NXOS 9K Disable POAP if pre_login_action == "nxos9k_disable_poap": try: # TODO: around 60 conn.expect( ["Starting Auto Provisioning", pexpect.TIMEOUT], timeout=timeout["pre_login"], ) conn.sendline("\r") conn.expect(["Abort Power On Auto Provisioning"]) conn.sendline("yes") conn.expect( ["Do you want to enforce secure password standard"]) conn.sendline("no") except pexpect.EOF: raise AnsibleError( f"on nxos9k_disable_poap EOF: {conn.before}") except pexpect.TIMEOUT: raise AnsibleError( f"on nxos9k_disable_poap TIMEOUT: {conn.before}") # XR 9K Reboot node first elif pre_login_action == "xr9k_reboot_node": if not HAS_GNS3FY: module.fail_json(msg=missing_required_lib("gns3fy"), exception=GNS3FY_IMP_ERR) server = Gns3Connector( url=f"{gns3fy_data['url']}:{gns3fy_data.get('port', 3080)}") lab = Project(name=gns3fy_data.get("project_name"), connector=server) lab.get() node = lab.get_node(gns3fy_data.get("node_name")) try: # TODO: around 60 conn.expect(["reboot: Restarting"], timeout=timeout["pre_login"]) node.stop() node.start() except pexpect.EOF: raise AnsibleError(f"on xr9k_reboot_node EOF: {conn.before}") except pexpect.TIMEOUT: node.stop() node.start() time.sleep(10) # TODO: around 30 i = conn.expect( ["Cisco IOS XR console", pexpect.EOF, pexpect.TIMEOUT], timeout=timeout["pre_login"], ) if i == 0: conn.sendline("\r") elif i == 1: try: # TODO: around 30 conn.expect(root_set_user_prompts, timeout=timeout["pre_login"]) except pexpect.EOF: conn.close(force=True) # TODO: Set as general timeout (which should be high) conn = pexpect.spawn( f"telnet {remote_addr} {port}", timeout=timeout["general"], maxread=4092, encoding="utf-8", searchwindowsize=2000, ignore_sighup=True, ) # Pause to send command after device initialization time.sleep(360) conn.sendline("\r") conn.sendline("\r") except pexpect.TIMEOUT: conn.sendline("\r") # Root user section if root_set_user_prompts: try: conn.expect(root_set_user_prompts) conn.sendline(user) except pexpect.EOF: raise AnsibleError(f"on root_set_user_prompts EOF: {conn.before}") except pexpect.TIMEOUT: raise AnsibleError( f"on root_set_user_prompts TIMEOUT: {conn.before}") if root_set_password_prompts: while True: try: conn.expect(root_set_password_prompts, timeout=5) conn.sendline(password) except pexpect.EOF: raise AnsibleError( f"on root_set_password_prompts EOF: {conn.before}") except pexpect.TIMEOUT: time.sleep(pause) conn.sendline("\r") break # Configuration Dialog section if config_dialog: # TODO: Was set as general timeout i = conn.expect( ["[bB]asic|initial [cC]onfiguration [dD]ialog", pexpect.TIMEOUT], timeout=timeout["config_dialog"], ) if i == 0: conn.sendline("no") time.sleep(pause) # TODO: Was set as general timeout i = conn.expect( ["terminate autoinstall?", pexpect.TIMEOUT], timeout=timeout["config_dialog"], ) if i == 0: conn.sendline("yes") time.sleep(pause) conn.sendline("\r") # Main login prompt section if login_prompt: # TODO: Was set as general timeout login_prompt_resolve( conn, login_prompt, user, password, enable_password, prompts, timeout=timeout["login_prompt"], ) # Post-login actions: Depends on the platform and image, for example it can be to # disable ZTP, enter CLI prompt or just wait for system initialization if post_login_action: if post_login_action == "eos_disable_ztp": conn.sendline("\r") i = conn.expect([">", *prompts]) if i == 0: enable_prompt_resolve(conn, enable_password, prompts) conn.sendline("zerotouch disable") time.sleep(pause) conn.sendline("wr mem") time.sleep(pause) conn.sendline("reload force") # TODO: Was set to 240 login_prompt_resolve( conn, login_prompt, user, password, enable_password, prompts, timeout=timeout["general"], use_prompts=False, ) elif post_login_action == "junos_enter_cli": conn.sendline("\r") i = conn.expect(["%", *prompts]) if i == 0: conn.sendline("cli") time.sleep(pause) elif post_login_action == "xr_wait_system": conn.sendline("\r") time.sleep(pause) # TODO: Was set to 60 i = conn.expect( [ "SYSTEM CONFIGURATION COMPLETED", pexpect.EOF, pexpect.TIMEOUT ], timeout=timeout["post_login"], ) if i == 0: conn.sendline("\r") # Commands push for comm in command: for prompt in prompts: try: conn.sendline("\r") time.sleep(pause) conn.expect(prompt) conn.sendline(comm) time.sleep(pause) result["changed"] = True except pexpect.EOF: raise AnsibleError(f"on commands enable EOF: {conn.before}") except pexpect.TIMEOUT: raise AnsibleError(f"on commands TIMEOUT: {conn.before}") conn.close() result.update(stdout=conn.before) module.exit_json(**result)
def main(): module = AnsibleModule( argument_spec=dict( url=dict(type="str", required=True), port=dict(type="int", default=3080), user=dict(type="str", default=None), password=dict(type="str", default=None, no_log=True), project_name=dict(type="str", default=None), project_id=dict(type="str", default=None), data=dict(type="str", default=None), dest=dict(type="str", required=True), state=dict(type="str", choices=["present", "absent"], default="present"), ), required_one_of=[["project_name", "project_id"]], ) if not HAS_GNS3FY: module.fail_json(msg=missing_required_lib("gns3fy"), exception=GNS3FY_IMP_ERR) result = dict(changed=False) server_url = module.params["url"] server_port = module.params["port"] server_user = module.params["user"] server_password = module.params["password"] project_name = module.params["project_name"] project_id = module.params["project_id"] data = module.params["data"] dest = module.params["dest"] state = module.params["state"] if state == "present" and data is None: module.fail_json(msg="Parameter needs to be passed: data", **result) # Create server session server = Gns3Connector( url=f"{server_url}:{server_port}", user=server_user, cred=server_password ) # Define the project if project_name is not None: project = Project(name=project_name, connector=server) elif project_id is not None: project = Project(project_id=project_id, connector=server) if project is None: module.fail_json(msg="Could not retrieve project. Check name", **result) # Retrieve project info project.get() # Try to get file data try: file_data = project.get_file(path=dest) except Exception as err: if "Not Found" in str(err): file_data = None else: module.fail_json(msg=str(err), exception=traceback.format_exc()) if state == "absent": if file_data is None or file_data == "": result.update(changed=False) else: # Delete project file data # As of now (GNS3 v2.2.rc5) the DELETE method is not allowed project_write_file(module, project, dest, "") result.update(changed=True) elif state == "present": if file_data == data: result.update(changed=False) else: project_write_file(module, project, dest, data) result.update(changed=True) module.exit_json(**result)
def main(): module = AnsibleModule( argument_spec=dict( url=dict(type="str", required=True), port=dict(type="int", default=3080), user=dict(type="str", default=None), password=dict(type="str", default=None, no_log=True), state=dict( type="str", required=True, choices=["opened", "closed", "present", "absent"], ), project_name=dict(type="str", default=None), project_id=dict(type="str", default=None), nodes_state=dict(type="str", choices=["started", "stopped"]), nodes_strategy=dict(type="str", choices=["all", "one_by_one"], default="all"), nodes_delay=dict(type="int", default=10), poll_wait_time=dict(type="int", default=5), nodes_spec=dict(type="list"), links_spec=dict(type="list"), ), supports_check_mode=True, required_one_of=[["project_name", "project_id"]], required_if=[["nodes_strategy", "one_by_one", ["nodes_delay"]]], ) result = dict(changed=False) if not HAS_GNS3FY: module.fail_json(msg=missing_required_lib("gns3fy"), exception=GNS3FY_IMP_ERR) if module.check_mode: module.exit_json(**result) server_url = module.params["url"] server_port = module.params["port"] server_user = module.params["user"] server_password = module.params["password"] state = module.params["state"] project_name = module.params["project_name"] project_id = module.params["project_id"] nodes_state = module.params["nodes_state"] nodes_strategy = module.params["nodes_strategy"] nodes_delay = module.params["nodes_delay"] poll_wait_time = module.params["poll_wait_time"] nodes_spec = module.params["nodes_spec"] links_spec = module.params["links_spec"] try: # Create server session server = Gns3Connector(url=f"{server_url}:{server_port}", user=server_user, cred=server_password) # Define the project if project_name is not None: project = Project(name=project_name, connector=server) elif project_id is not None: project = Project(project_id=project_id, connector=server) except Exception as err: module.fail_json(msg=str(err), **result) # Retrieve project information try: project.get() pr_exists = True except Exception as err: pr_exists = False reason = str(err) if state == "opened": if pr_exists: if project.status != "opened": # Open project project.open() # Now verify nodes if nodes_state is not None: # Change flag based on the nodes state result["changed"] = nodes_state_verification( expected_nodes_state=nodes_state, nodes_strategy=nodes_strategy, nodes_delay=nodes_delay, poll_wait_time=poll_wait_time, project=project, ) else: # Means that nodes are not taken into account for idempotency result["changed"] = True # Even if the project is open if nodes_state has been set, check it else: if nodes_state is not None: result["changed"] = nodes_state_verification( expected_nodes_state=nodes_state, nodes_strategy=nodes_strategy, nodes_delay=nodes_delay, poll_wait_time=poll_wait_time, project=project, ) else: module.fail_json(msg=reason, **result) elif state == "closed": if pr_exists: if project.status != "closed": # Close project project.close() result["changed"] = True else: module.fail_json(msg=reason, **result) elif state == "present": if pr_exists: if nodes_spec is not None: # Need to verify if nodes exist _nodes_already_created = [node.name for node in project.nodes] for node_spec in nodes_spec: if node_spec["name"] not in _nodes_already_created: # Open the project in case it was closed project.open() create_node(node_spec, project, module) result["changed"] = True if links_spec is not None: for link_spec in links_spec: project.open() # Trigger another get to refresh nodes attributes project.get() # Link verification is already built in the library created = create_link(link_spec, project, module) if created: result["changed"] = True else: # Create project project.create() # Nodes section if nodes_spec is not None: for node_spec in nodes_spec: create_node(node_spec, project, module) # Links section if links_spec is not None: for link_spec in links_spec: create_link(link_spec, project, module) result["changed"] = True elif state == "absent": if pr_exists: # Stop nodes and close project to perform delete gracefully if project.status != "opened": # Project needs to be opened in order to be deleted... project.open() project.stop_nodes(poll_wait_time=0) project.delete() result["changed"] = True else: module.exit_json(**result) # Return the project data result["project"] = return_project_data(project) module.exit_json(**result)
from gns3fy import Gns3Connector, Project server = Gns3Connector("http://localhost:3080") project = Project(name="topology_container", connector=server) project.get() project.open() print(project)
def main(): module = AnsibleModule( argument_spec=dict( url=dict(type="str", required=True), user=dict(type="str", default=None), password=dict(type="str", default=None, no_log=True), port=dict(type="int", default=3080), state=dict(type="str", required=True, choices=["present", "absent", "restore"]), project_name=dict(type="str", default=None), project_id=dict(type="str", default=None), snapshot_name=dict(type="str", default=None), snapshot_id=dict(type="str", default=None), ), required_one_of=[ ["project_name", "project_id"], ["snapshot_name", "snapshot_id"], ], ) result = dict(changed=False) if not HAS_GNS3FY: module.fail_json(msg=missing_required_lib("gns3fy"), exception=GNS3FY_IMP_ERR) server_url = module.params["url"] server_port = module.params["port"] server_user = module.params["user"] server_password = module.params["password"] project_name = module.params["project_name"] project_id = module.params["project_id"] snapshot_name = module.params["snapshot_name"] snapshot_id = module.params["snapshot_id"] state = module.params["state"] try: # Create server session server = Gns3Connector(url=f"{server_url}:{server_port}", user=server_user, cred=server_password) # Define the project if project_name is not None: project = Project(name=project_name, connector=server) elif project_id is not None: project = Project(project_id=project_id, connector=server) # Collect project and snapshots data project.get() snapshot = project.get_snapshot(name=snapshot_name, snapshot_id=snapshot_id) if state == "present": if snapshot is None: # Create the snapshot if not snapshot_name: module.fail_json( msg="Need to specify snapshot name for creation", **result) project.create_snapshot(name=snapshot_name) result["changed"] = True result["snapshot"] = project.get_snapshot( name=snapshot_name, snapshot_id=snapshot_id) else: result["snapshot"] = snapshot elif state == "absent": if snapshot: # Delete snapshot project.delete_snapshot(name=snapshot_name, snapshot_id=snapshot_id) result["changed"] = True elif state == "restore": if not snapshot: module.fail_json(msg="Snapshot not found", **result) # Restore snapshot project.restore_snapshot(name=snapshot_name, snapshot_id=snapshot_id) result["changed"] = True result["snapshot"] = snapshot module.exit_json(**result) except Exception as err: module.fail_json(msg=str(err), **result)
from gns3fy import Gns3Connector, Project from tabulate import tabulate server = Gns3Connector("http://localhost:3080") lab = Project(name="topology_container", connector=server) lab.get() print(lab) print('\n--------------------------------\n') nodes = lab.nodes_summary(is_print=False) print(tabulate(nodes)) print('\n--------------------------------\n') links = lab.links_summary(is_print=False) print(tabulate(links))
def OpenProject(project_id, project_name, gns3_server): project = Project(project_id=project_id, name=project_name, connector=gns3_server) project.get() project.open()
def main(): module = AnsibleModule( argument_spec=dict( url=dict(type="str", required=True), port=dict(type="int", default=3080), user=dict(type="str", default=None), password=dict(type="str", default=None, no_log=True), state=dict( type="str", required=True, choices=["started", "stopped", "suspended", "reload"], ), project_name=dict(type="str", default=None), project_id=dict(type="str", default=None), node_name=dict(type="str", default=None), node_id=dict(type="str", default=None), retry=dict(type="bool", default=False), poll_wait_time=dict(type="int", default=5), force_project_open=dict(type="bool", default=False), ), required_one_of=[["project_name", "project_id"], ["node_name", "node_id"]], ) result = dict(changed=False) if not HAS_GNS3FY: module.fail_json(msg=missing_required_lib("gns3fy"), exception=GNS3FY_IMP_ERR) server_url = module.params["url"] server_port = module.params["port"] server_user = module.params["user"] server_password = module.params["password"] state = module.params["state"] project_name = module.params["project_name"] project_id = module.params["project_id"] node_name = module.params["node_name"] node_id = module.params["node_id"] retry = module.params["retry"] poll_wait_time = module.params["poll_wait_time"] force_project_open = module.params["force_project_open"] try: # Create server session server = Gns3Connector(url=f"{server_url}:{server_port}", user=server_user, cred=server_password) # Define the project if project_name is not None: project = Project(name=project_name, connector=server) elif project_id is not None: project = Project(project_id=project_id, connector=server) if project is None: module.fail_json(msg="Could not retrieve project. Check name", **result) project.get() if project.status != "opened" and force_project_open: project.open() # Retrieve node if node_name is not None: node = project.get_node(name=node_name) elif node_id is not None: node = project.get_node(node_id=node_id) if node is None: module.fail_json(msg="Could not retrieve node. Check name", **result) except Exception as err: module.fail_json(msg=str(err), **result) # Apply state change result["changed"] = state_verification(expected_state=state, node=node, retry=retry, poll_wait_time=poll_wait_time) # Return the node data result["node"] = return_node_data(node) module.exit_json(**result)