ktbyers / scp_sidecar

Ansible modules using SCP and SSH to transfer files to network devices
Apache License 2.0
24 stars 13 forks source link

SCP failure #14

Open sakabio opened 7 years ago

sakabio commented 7 years ago

OS Ubuntu 16.04 ansible 2.3.2.0

got an scp error using the module.

"msg": "value of enable_scp must be one of: y,yes,on,1,true,1,True,n,no,off,0,false,0,False, got: True"

fatal: [1.2.3.4]: FAILED! => { "changed": false, "failed": true, "invocation": { "module_args": { "dest_file": "upload.txt", "dest_file_system": "flash:", "enable_scp": "True", "host": "1.2.3.4", "overwrite": "True", "password": "cisoco", "port": "22", "source_file": "/etc/ansible/playbooks/test.txt", "username": "cisco" } }, "msg": "value of enable_scp must be one of: y,yes,on,1,true,1,True,n,no,off,0,false,0,False, got: True" }

playbook:

--

ktbyers commented 7 years ago

Does it work if you try:

enable_scp: True
sakabio commented 7 years ago

No does not work

ktbyers commented 7 years ago

@sakabio Okay, I will need to try to reproduce this.

sakabio commented 7 years ago

Thanks so much.

ktbyers commented 7 years ago

@sakabio At a higher-level what are you trying to accomplish i.e. what is the purpose of the file transfer?

sakabio commented 7 years ago

Trying to upload IOS images to 1224 switches and dont want to do it manually. They need upgrading.

ktbyers commented 7 years ago

Nice!

ktbyers commented 7 years ago

Make sure you increase the number of forks using the --forks argument to Ansible to that more devices are done in parallel.

ktbyers commented 7 years ago

@sakabio Testing this now...

ktbyers commented 7 years ago

@sakabio Okay, I pushed a fix here (it was a bug in my code i.e. Ansible had changed things and I hadn't updated to the new format for arguments).

https://github.com/ktbyers/scp_sidecar/commit/993ea9a4d1cb1562f833b50533d5b2284fe68773

You will need to refresh your code to get this change.

Let me know if this works now.

sakabio commented 7 years ago

You're the man, worked like a charm.

ktbyers commented 7 years ago

Let me know how your OS upgrade goes.

sakabio commented 7 years ago

@ktbyers Hello there, can you make the destination file system a variable so it can be specified. I would like to loop through a switch stack and load the IOS images to the individual members.

ktbyers commented 7 years ago

There already is a variable for this:

dest_file_system: "flash:"

It defaults to the above, but you can set it.

Does that accomplish what you are looking for?

sakabio commented 7 years ago

@ktbyers

I tried setting it and got an error.

The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_482Ekq/ansible_module_cisco_file_transfer.py", line 77, in <module>
    main()
  File "/tmp/ansible_482Ekq/ansible_module_cisco_file_transfer.py", line 73, in main
    module.fail_json(msg="File transfer to remote device failed")
  File "/usr/local/lib/python2.7/dist-packages/netmiko/scp_handler.py", line 87, in __exit__
    raise exc_type(exc_value)
ValueError: Unexpected output from check_file_exists

failed: [1.2.3.5] (item=1) => {
    "failed": true,
    "item": "1",
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_482Ekq/ansible_module_cisco_file_transfer.py\", line 77, in <module>\n    main()\n  File \"/tmp/ansible_482Ekq/ansible_module_cisco_file_transfer.py\", line 73, in main\n    module.fail_json(msg=\"File transfer to remote device failed\")\n  File \"/usr/local/lib/python2.7/dist-packages/netmiko/scp_handler.py\", line 87, in __exit__\n    raise exc_type(exc_value)\nValueError: Unexpected output from check_file_exists\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE",
    "rc": 0
}
ktbyers commented 7 years ago

Here is what check_file_exists does:

    def check_file_exists(self, remote_cmd=""):
        """Check if the dest_file already exists on the file system (return boolean)."""
        if self.direction == 'put':
            if not remote_cmd:
                remote_cmd = "dir {0}/{1}".format(self.file_system, self.dest_file)
            remote_out = self.ssh_ctl_chan.send_command_expect(remote_cmd)
            search_string = r"Directory of .*{0}".format(self.dest_file)
            if 'Error opening' in remote_out:
                return False
            elif re.search(search_string, remote_out):
                return True
            else:
                raise ValueError("Unexpected output from check_file_exists")
        elif self.direction == 'get':
            return os.path.exists(self.dest_file)

Can you post the part of your playbook where you set dest_file_system?

sakabio commented 7 years ago

This is what I wanted to do.

- name: TEST FILE UPLOAD IPBase 
      cisco_file_transfer:
        source_file: "/cisco_ios/c3750-ipbasek9-mz.122-55.SE11.bin"
        dest_file_system: "flash{{ item }}:"
        dest_file: c3750-ipbasek9-mz.122-55.SE11.bin
        enable_scp: True
        host: "{{ inventory_hostname }}"
        username: "{{ username }}"
        password: "{{ password }}"
      with_items:
        - "{{ file_sys }}"
      when:
        - '"ipbase" in ansible_net_image'
        - '"12" in ansible_net_image'
        - space_available

This allows me to loop through each stack and uplod the file, this works on the 3750 stacks however fail on WS-C3650-48PD.

I also notice I get this error when a copy is completed for bulk switches.

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: socket.error: Socket is closed fatal: [1.3.5.6]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Traceback (most recent call last):\n File \"/tmp/ansible_gKgh_i/ansible_module_cisco_file_transfer.py\", line 77, in <module>\n main()\n File \"/tmp/ansible_gKgh_i/ansible_module_cisco_file_transfer.py\", line 73, in main\n module.fail_json(msg=\"File transfer to remote device failed\")\n File \"/usr/local/lib/python2.7/dist-packages/netmiko/scp_handler.py\", line 87, in __exit__\n raise exc_type(exc_value)\nsocket.error: Socket is closed\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 0} I prepared a playbook to do an md5 verification after the copy is completed.

I was able to do a 183 switches in 3 hours will 50 flows. Currently running copy for 314 switches.

For 3750 Stacks I am able to copy to a max of 3 stacks then it times out.

Started with ansible just last thursday. I am a great fan of your work, will take a class soon.

ktbyers commented 7 years ago

The cisco_file_transfer will automatically do an MD5 as part of the process. It will also automatically check that there is space available.

The error you have above is:

Socket is closed

So it sounds like the remote switch closed either the SSH or the SCP channel (or they were never open).

You might want to test a manual SCP on this device and see if it works properly (to isolate whether something is not right with the SCP process versus the module code).