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), node_name=dict(type="str", default=None), node_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"], ["node_name", "node_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"] node_name = module.params["node_name"] node_id = module.params["node_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() # Define the 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) # Try to get file data try: file_data = node.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 node file data # As of now (GNS3 v2.2.rc5) the DELETE method is not allowed node_write_file(module, node, dest, "") result.update(changed=True) elif state == "present": if file_data == data: result.update(changed=False) else: node_write_file(module, node, dest, data) result.update(changed=True) 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), 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)