cancel
Showing results for 
Search instead for 
Did you mean: 

Powershell: Invoke-RESTmethod on /mgmt/tm/sys/ucs (403) Forbidden error

KeyClacker
Altocumulus
Altocumulus

I'm fairly experienced with Powershell and have used the Invoke-RestMethod cmdlet, and vendor documentation, to automate some things before.  I've just inherited management of an HA pair of F5 BIG-IPs.  We're not in a position to get BIG-IQ right now, and from looking at notes the previous admin was just logging in and manually creating a UCS archive and downloading it on the weekly.

Of course my first thought was that I could automate this. I was able to successfully authenticate against one of the appliances with Invoke-RestMethod and do an HTTP GET to retrieve a  list of current UCS files present.  However, when I change the method to POST and add in the appropraite Body parameters (in JSON) I get a 403 forbidden error:

 

 

{"code":403,"message":"Operation is not allowed on component /sys/ucs.","errorStack":[],"apiError":1}

 

 

the documentation here seems to allude that this should be possible:

K13225405 

Here's more or less what I'm working with so far:

 

 

$uri = "/mgmt/tm/sys/ucs"
$BigIP = "192.168.1.10"
$link = "https://$BigIP$uri"
$headers = @{}
$headers.Add("ServerHost", $Bigip)
$headers.Add("Content-Type", "application/json")
$Body = @{
    Name = "/var/local/ucs/test_ucs.ucs"
    Command = "save"
}
$mycreds = Get-Credential

$obj = Invoke-RestMethod -Method POST -Headers $headers -Body ($Body | ConvertTo-Json) -Uri $link -Credential $mycreds

 

 

15 REPLIES 15

xuwen
Cirrus
Cirrus

i suggest you use f5 python sdk api: f5-sdk

here is the code to save sys ucs file and name its filename "/var/local/ucs/test.ucs":

from f5.bigip import ManagementRoot

mgmt = ManagementRoot("192.168.5.109", 'admin', 'xt32112300')

"""save sys ucs name /var/local/ucs/test.ucs"""
mgmt.tm.sys.ucs.exec_cmd(command='save', name='/var/local/ucs/test.ucs')

"""check system all sys ucs filename"""
for i in mgmt.tm.sys.ucs.load().items:
print(i['apiRawValues']['filename'])

 

Appreciate that, but we don't use Python anywhere in our organization.  If Python can do it using the same REST API then I would think anything could.

SamCo
Cirrus
Cirrus

Did you try to make the same POST request with a different UCS name ?

Maybe there is already an existing one on your box with the same name, in that case you request could be blocked to avoid to override it.

use datetime to rename format ucs filename and make it not be the same

from datetime import datetime

'/var/local/ucs/test_{}.ucs'.format(datetime.now().strftime('%Y-%m-%d'))

 

I have not tried another account as this is my account, but I could potentially create an account just for this. However, my account is an admin, and it does let me authenticate via the API to do a GET request and get a list of the UCS archives already on the appliance, for which there is one. And there is no name collision.  This is from F5's documentation:

<POST> /mgmt/tm/sys/ucs -d '{"command":"save","name":"/var/local/ucs/test_ucs.ucs"}'


However, in another document somewhere else they only provide the filename with no full path, and no file extension.  I've tried all of those combos with the same result. 

Maybe I have not been clear enough : the credential are fine, I mean the filename :

You have a 403 for "/var/local/ucs/test_ucs.ucs", have you tried "/var/local/ucs/test_ucs_XXX.ucs" ?

 

Cheers,

Sam

Thanks Sam. I have tried that. I've tried:

/var/local/ucs/test_ucs.ucs

/var/local/ucs/test_ucs123.ucs

/var/local/ucs/test_ucs123

test_ucs

test_ucs123

 

all produce the same error message.  I'm currently attempting to combine some methodology from the POSH-LTM-Rest module found here and the code i've been working on already. The documentation doesn't call it out anywhere but I wonder if you have to retrieve an F5 session token before you can do anything using the POST method. 

Looking at this article, it looks like people manage to make it with standard credential :

https://community.f5.com/t5/technical-forum/how-can-i-call-icontrolrest-to-save-and-load-configurati...

Good luck 😉

So this is the example syntax that i've been going on (from that thread and documentation):

curl -v -sk -u admin:admin https://10.10.10.10/mgmt/tm/sys/ucs -H "Content-Type: application/json" -X POST -d '{"command":"save","name":"test.ucs"}'

I'm on a Windows box though, and something about that doesn't translate well to Curl.exe. It gets mad about non-json content.  So, I spun up a Linux VM really quick and ran that exact syntax and it didn't error out AND it created a test.ucs.  Now  I just need to understand what's different between that curl request and what i'm doing with Invoke-RestMethod in Powershell, because I'm not seeing it. 

quick update before going in to a meeting.

I changed how i'm generating the $Body variable to just be a here-string with straight up json in it, instead of a hashtable i convert to json, and the request worked. 

omg...it wasn't even that. It was case.  Even though Powershell is case insensitive I'm so used to doing camel case everywhere that I did "Command" and "Name" instead of "command" and "name" for my json body.

Now to figure out how to download a ucs....

JRahm
Community Manager
Community Manager

There are a couple nuances with downloading files. First, the /sys/global-settings has a file whitelist attribute that must have your folder location listed. Then, you have to actually have a restjavad worker attached to that location. AFAIK, there are only a few locations you can upload/download from with iControl REST:

Description Method URI Path
ASM POST /mgmt/tm/asm/file-transfer/uploads/ ??
ASM GET /mgmt/tm/asm/file-transfer/downloads/ ??
image POST /mgmt/cm/autodeploy/software-image-uploads/ /shared/images/
image/files GET /mgmt/cm/autodeploy/software-image-downloads/ /shared/images/
qkview GET /mgmt/shared/file-transfer/qkview-downloads/ /var/tmp/
ucs GET /mgmt/shared/file-transfer/ucs-downloads/ /var/local/ucs/
files POST /mgmt/shared/file-transfer/uploads/ /var/config/rest/downloads/

I updated my Demystifying iControl REST article on transferring files with this expanded table.

thanks JRahm. I wanted to download UCS files which look to reside  in /var/local/ucs/* so I should have been all good to go, but when I downloaded a UCS it was only 1MB. Then I read in an F5 doc that the iControl REST API is limited to 1MB downloads. 

Re-reading the F5 Python SDK I see they managed to build a little loop that gets the file size and somehow manages to download it in little 1MB chunks. But, according to one of the "issues" posted in Github, it's incredibly slow.  So, I've decided to just give up on scripting this with Powershell.  

I can create a UCS archive via Powershell, and I can list the current ones, but it looks like downloading is a no go. Save for doing something like SCP or something. 

JRahm
Community Manager
Community Manager

yeah, you have to track the content-range header and grab chunks at a time. That's what we do with the python sdks. we have download/upload methods that manage that for us.

that's what I was seeing looking through the SDK on github.  While I can kind of make sense of it, I don't know Invoke-RestMethod and the Content-Range header well enough to begin to tackle this.