[cisco-voip] CUCM Bulk TFTP File Upload

Ryan Ratliff (rratliff) rratliff at cisco.com
Wed Jun 6 11:35:08 EDT 2018


If you know the files you can use curl or your favorite http package to get them http://tftp.ip:6970/.

On some versions you can get http://tftp.ip:6970/filelist.txt to get an index of files. I think that file went away in 11.5 or 12.0 with enhancements made to serving static files.

-Ryan

On Jun 6, 2018, at 10:18 AM, Charles Goldsmith <wokka at justfamily.org<mailto:wokka at justfamily.org>> wrote:

Thanks very much for this!  Has anyone worked out an easy way to bulk download this data?  Say you have to rebuild or add a node to an existing cluster and the customer doesn't have all of this info archived properly?


On Mon, Jun 4, 2018 at 1:20 PM Brian Meade <bmeade90 at vt.edu<mailto:bmeade90 at vt.edu>> wrote:
Now on Github- https://github.com/bmeade90/BulkTFTP

On Mon, Jun 4, 2018 at 8:47 AM, Brian Meade <bmeade90 at vt.edu<mailto:bmeade90 at vt.edu>> wrote:
Thanks for cleaning that up Anthony!

My main goal with this is to bulk upload entire directories and all the sub-directories so I can easily upload all the Desktops directories and such.

Since I'm bulk uploading so many files, I decided to just do a single node at a time but your edit should work fine to make this multi-node.

Attached my finalized script I was able to use to upload a few hundred files to a 4-node cluster on Friday.

On Sat, Jun 2, 2018 at 3:19 PM, Anthony Holloway <avholloway+cisco-voip at gmail.com<mailto:avholloway+cisco-voip at gmail.com>> wrote:
Here's your code re-worked a little Brian, for you or for anyone else, and I tested it on 11.5 and it works.  I did not put in any error handling, so I'll leave that up to you.  You can do things like Try/Catch or checking for resp.status_code == 200, file existence checking, etc.  I figure, knowing how to make it work was the challenge, not error handling, so I left that out.

# Install Python 2.7 and choose the option to add to path (off by default)
# Then install two modules
#  C:\>pip install requests
#  C:\>pip install BeautifulSoup
# Then run the program
#  C:\>python tftp.py

import requests
from BeautifulSoup import BeautifulSoup
requests.packages.urllib3.disable_warnings()

tftp_host = ""
tftp_user = ""
tftp_pass = ""
tftp_file = ""
tftp_path = ""

url_base = "https://{}/cmplatform/".format(tftp_host)
url_login = "{}j_security_check".format(url_base)
url_upload = "{}tftpFileUpload.do".format(url_base)

# Allows us to keep track of our login session
print "\nLogging in to {}...".format(tftp_host),
connection = requests.Session()

# Start a new session by simply access a page on the server
resp = connection.get(url_base, verify = False)

# Our login form data
form_data = {
"appNav": "cmplatform",
"j_username": tftp_user,
"j_password": tftp_pass
}

# Our login submission to the server
resp = connection.post(url_login, verify = False, data = form_data)
print "Success!\n"

# We need to grab the token the server gives us, so we can pass it back upon upload
print "Grabbing a new token...",
soup = BeautifulSoup(connection.get(url_upload, verify = False).content)

# It's a hidden input element on the upload form with the name of "token"
token = soup.find("input", {"name": "token"}).get("value")
print "Found! [{}]\n".format(token)

# Our upload form submission data
payload = {
"struts.token.name<http://struts.token.name/>": (None, "token"),
"token": (None, token),
"file": (tftp_file, open(tftp_file, "rb"), {"Content-Type": "text/plain"}),
"directory": (None, tftp_path)
}

# Our upload submission to the server
print "Uploading file: {}...".format(tftp_file),
resp = connection.post(url_upload, verify = False, files = payload)
print "Success!\n"

print "Done!"

If you want multiple server/multiple file support, it's really just a small modification (highlighted in red):

# Install Python 2.7 and choose the option to add to path (off by default)
# Then install two modules
#  C:\>pip install requests
#  C:\>pip install BeautifulSoup
# Then run the program
#  C:\>python tftp.py

import requests
from BeautifulSoup import BeautifulSoup
requests.packages.urllib3.disable_warnings()

tftp_hosts = [
"host1",
"hostN"
]
tftp_user = ""
tftp_pass = ""

tftp_files = [
"file1",
"fileN"
]
tftp_path = ""

for tftp_host in tftp_hosts:

url_base = "https://{}/cmplatform/".format(tftp_host)
url_login = "{}j_security_check".format(url_base)
url_upload = "{}tftpFileUpload.do".format(url_base)

# Allows us to keep track of our login session
print "\nLogging in to {}...".format(tftp_host),
connection = requests.Session()

# Start a new session by simply access a page on the server
resp = connection.get(url_base, verify = False)

# Our login form data
form_data = {
"appNav": "cmplatform",
"j_username": tftp_user,
"j_password": tftp_pass
}

# Our login submission to the server
resp = connection.post(url_login, verify = False, data = form_data)
print "Success!\n"
for tftp_file in tftp_files:

# We need to grab the token the server gives us, so we can pass it back upon upload
print "Grabbing a new token...",
soup = BeautifulSoup(connection.get(url_upload, verify = False).content)

# It's a hidden input element on the upload form with the name of "token"
token = soup.find("input", {"name": "token"}).get("value")
print "Found! [{}]\n".format(token)

# Our upload form submission data
payload = {
"struts.token.name<http://struts.token.name/>": (None, "token"),
"token": (None, token),
"file": (tftp_file, open(tftp_file, "rb"), {"Content-Type": "text/plain"}),
"directory": (None, tftp_path)
}

# Our upload submission to the server
print "Uploading file: {}...".format(tftp_file),
resp = connection.post(url_upload, verify = False, files = payload)
print "Success!\n"

print "Done!"

On Fri, Jun 1, 2018 at 3:38 PM Brian Meade <bmeade90 at vt.edu<mailto:bmeade90 at vt.edu>> wrote:
So just re-read through everything and sure enough I was sending to the wrong IP when running the script.  No wonder it's shown as uploading successfully the entire time.

Thanks for you and Stephen's assistance!

Tommy, BTW you can remove a lot of the manual set headers if you want to clean yours up.  It seems to work without them.

Thanks,
Brian Meade

On Fri, Jun 1, 2018 at 4:10 PM, Schlotterer, Tommy <tschlotterer at presidio.com<mailto:tschlotterer at presidio.com>> wrote:



Just tested on CUCM 11.5, worked just fine.

Thanks

Tommy

From: bmeade90 at gmail.com<mailto:bmeade90 at gmail.com> [mailto:bmeade90 at gmail.com<mailto:bmeade90 at gmail.com>] On Behalf Of Brian Meade
Sent: Friday, June 1, 2018 4:06 PM
To: Schlotterer, Tommy <tschlotterer at presidio.com<mailto:tschlotterer at presidio.com>>
Cc: cisco-voip voyp list <cisco-voip at puck.nether.net<mailto:cisco-voip at puck.nether.net>>
Subject: Re: [cisco-voip] CUCM Bulk TFTP File Upload

EXTERNAL EMAIL




Thanks Tommy!

Have you tested against CUCM 11.x okay?

I need to build the dependencies to fully run yours.  I tried pulling out the important upload code but seeing the same issue I'm having with my code.

Thanks,
Brian Meade

On Fri, Jun 1, 2018 at 1:18 PM, Schlotterer, Tommy <tschlotterer at presidio.com<mailto:tschlotterer at presidio.com>> wrote:
Brian,

Here is my really hacky python script to do this.

Thanks

Tommy

From: cisco-voip [mailto:cisco-voip-bounces at puck.nether.net<mailto:cisco-voip-bounces at puck.nether.net>] On Behalf Of Brian Meade
Sent: Friday, June 1, 2018 9:54 AM
To: cisco-voip voyp list <cisco-voip at puck.nether.net<mailto:cisco-voip at puck.nether.net>>
Subject: [cisco-voip] CUCM Bulk TFTP File Upload

EXTERNAL EMAIL




Does anyone have a working script for this?

I put together a script in python to do this but hitting some issues.

Right now I’ve got it to the point that it’s trying to upload a single file.

I used Fiddler to copy what I saw for a working request through a browser.

I first do a Get to the cmplatform page to get a cookie.

I then do a Post to the /cmplatform/j_security_check page to authenticate that cookie.

I then do a Get to /cmplatform/tftpFileUpload.do to get a Struts Token.

I then do a Post to /cmplatform/tftpFileUpload.do with the Struts token, filename, and directory details.

This looks to be successful as I get a "File uploaded successfully" message returned but then I can't find the file on the TFTP File Management page.

I tried using the curl methods I found here ( https://communities.cisco.com/docs/DOC-43506 ) but no luck there.  Not sure if this works in 11.5 without grabbing the Struts token.   Without a token, I get an error message saying something to the affect of I hit the Submit button twice.

Here's what it looks like when my script runs in Fiddler:
[X]


This looks almost exactly like the real example through a browser I captured minus a few headers I tried manually adding with no luck.

Python script attached.


Tommy Schlotterer | Systems Engineer - Collaboration
Presidio (NASDAQ: PSDO) | presidio.com<http://presidio.com/>
20 N Saint Clair 3rd Floor, Toledo, OH 43604<https://maps.google.com/?q=20+N+Saint+Clair+3rd+Floor,+Toledo,+OH+43604&entry=gmail&source=g>
D: 419.214.1415<tel:(419)%20214-1415> | C: 419.706.0259<tel:(419)%20706-0259> | tschlotterer at presidio.com<mailto:tschlotterer at presidio.com>


[Future. Built.]<http://www.presidio.com/>

Follow us:

[Follow Presidio on Twitter]<http://www.twitter.com/presidio>


This message w/attachments (message) is intended solely for the use of the intended recipient(s) and may contain information that is privileged, confidential or proprietary. If you are not an intended recipient, please notify the sender, and then please delete and destroy all copies and attachments. Please be advised that any review or dissemination of, or the taking of any action in reliance on, the information contained in or attached to this message is prohibited.




[Future. Built.]<http://www.presidio.com/>




Follow us:

[Follow Presidio on Twitter]<http://www.twitter.com/presidio>







_______________________________________________
cisco-voip mailing list
cisco-voip at puck.nether.net<mailto:cisco-voip at puck.nether.net>
https://puck.nether.net/mailman/listinfo/cisco-voip


_______________________________________________
cisco-voip mailing list
cisco-voip at puck.nether.net<mailto:cisco-voip at puck.nether.net>
https://puck.nether.net/mailman/listinfo/cisco-voip
_______________________________________________
cisco-voip mailing list
cisco-voip at puck.nether.net<mailto:cisco-voip at puck.nether.net>
https://puck.nether.net/mailman/listinfo/cisco-voip

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://puck.nether.net/pipermail/cisco-voip/attachments/20180606/1e320bc2/attachment.html>


More information about the cisco-voip mailing list